今天小K问了我一个面试题,怎么实现一个实reverse方法,在实现的过程当中我仍是犯了一些错,实现完之后,对一些知识点的理解又加深了。面试
最开始我是这么写的数组
var arr = [1,2,3,4,5] var reverse1 = function (arr) { let newArr = [] while (arr.length>0){ newArr.push(arr.pop()) } console.log(arr,newArr) // [],[5,4,3,2,1] arr = newArr //让arr等于反转后的新数组 console.log(arr) // [5,4,3,2,1] return arr } reverse1(arr)
结果有点打脸函数
console.log(arr) // []
上面的现象显示:我将arr当参数传入reverse1里面,我能够改变arr里面的内容可是我却没法改变arr
(arr由[1,2,3,4,5]pop()五次变成[ ],可是随后的赋值操做却没有成功)
为何会出现这个问题,咱们得从函数的参数传递方式提及this
函数的参数都是值传递
怎么理解这句话,按照高程
的说法,若是这里是引用传递,那么我在代码第8行已经让arr变成了[5,4,3,2,1],那么外面的arr也应该变,可是如今外面arr倒是[ ],因此函数的参数的传递方法都是值传递prototype
若是你以为这么说仍是比较抽象,你能够听听鄙人陋见,咱们彻底能够把js里面数组名当成一个指针变量,储存的是实际的数组对象的地址。指针意味着咱们经过它能够访问它指向的对象。变量意味者我能够改变这个变量。指针
在函数参数里面当咱们传入一个arr的时候,实际传递的是一个形参address1,储存arr这个对象在内存里的地址,address1=xxxx xxxxx xxxx xxx1。经过address1能够对arr进行任何操做,一旦如今我为address1赋上新的地址值,也就是address1=xxxx xxxxx xxxx xxx2。address1就和arr失去了联系。此时arr仍是在xxxx xxxxx xxxx xxx1上,而且至少在当前的reverse1方法中不会再被改变了,由于没有哪一个指针能指向它了。code
ok说了这么多,实际想说的是,你在方法中能够经过索引,经过原生方法操做一个当参数传进来的数组,可是绝对不容许对数组名直接进行赋值
那么这个题目咱们就能够尝试使用原生方法来操做传进来的数组,这里提供一种思路对象
var arr = [1,2,3,4,5] var reverse1 = function () { for(var i = 0; i < arr.length; i ++){ arr.splice(i,0,arr.pop()) } } reverse1(arr) console.log(arr) // [5,4,3,2,1]
可是咱们能够看到上面的方法仍是不是很好,这是由于这个reverse1貌似只能对arr进行操做,耦合性太强,咱们须要解耦,让reverse1对全部的数组都适用,这里适用this和原型方面的知识索引
//一个完美的写法: Array.prototype.reverse1 = function () { for(var i = 0; i < this.length; i ++){ //this 解耦 this.splice(i,0,this.pop()) } return this }
今天介绍了一下reverse的实现思路,this解耦,以及函数参数是值传递这么一个概念,
建议在方法中经过索引,经过原生方法改变一个当参数传进来的数组,可是绝对不容许对数组名直接进行赋值
但愿对你们有所帮助。内存