Array.prototype.slice.apply可以转换数组的原理

luoqua

我们经常可以看到这种写法。

function test(){  
 //将参数转为一个数组  
 var args = Array.prototype.slice.apply(arguments);
  console.log(args)
} 

一般我们网上看到解释都是,对于js中的arguments来说,并不是一个真正的数组,可以叫它伪数组,通过Array.prototype.slice.apply方法,可以将其转化成数组,那让我们调用这个函数,看下函数中的参数数组。

test(11,22);  //[11,12]

同样的,我们可以先输出下函数内部的arguments。

console.log(arguments);     //[11,12,callee:,length:2]

可以看到,arguments确实不是一个纯数组。那么slice方法在将处理arguments并返回一个参数数组这个过程中,具体做了什么呢。让我们先了解下slice这个方法。
slice()方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象,且原始数组不会被修改。
语法

array.slice(begin,end);

参数
begin 可选,从该索引出开始提取原数组中的元素(从0开始)。如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。如果省略begin,则slice从索引0开始。
end 可选。从该索引处结束提取原数组元素(从0开始)。slice会提取原数组中索引从begin到end的所有元素(包含begin,但不包含end)。
slice(1,4)提取原数组中的第二个元素开始直到第四个元素的所有元素(索引为1,2,3的元素)。
如果该参数为负数,则表示在数组中的倒数第几个元素结束抽取。slice(-2,-1)表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)
另外:如果end被省略,则slice会一直提取到数组末尾。
如果end大于数组长度,slice也会一直提取到原数组末尾。
返回值
一个含有提取元素的新数组。
关于基本的slice的使用,我相信很容易理解也很容易使用。但是slice有两个特殊的地方.slice不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:
1、如果该元素是个对象引用(不是实际的对象),slice会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中这个元素也会发生改变。这个很好理解,看一个例子就明白。

var aa_aa = {x:1};
var aa_arr = [1,2,aa_aa];
aa_aa.x = 2;
console.log(aa_arr.slice(-1)); //[{x:2}]

2、对于字符串、数字及布尔值来说(不是String、Number或者Boolean对象),slice会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。这个也很容易理解,可参考我之前的文章,对引用类型和基本类型的介绍。
如果向两个数组任一个添加了新元素,则另一个不会受到影响。
以上内容来自MDN关于slice方法的介绍。
那现在我们知道,slice方法拥有将原数组中的元素浅复制到新数组中,并返回一个新数组的能力。那对于这里的函数。首先,利用apply方法让当前的函数内的arguments可以使用slice方法,然后slice方法将arguments中的11和12两个元素浅复制到新数组,并返回,这就实现了从arguments到数组的转变

function test(){  
 //将参数转为一个数组  
 var args = Array.prototype.slice.apply(arguments);
  console.log(args)
} 
test(11,12);

参考链接:
https://developer.mozilla.org...

阅读 3.7k
132 声望
3 粉丝
0 条评论
132 声望
3 粉丝
文章目录
宣传栏