我知道它是用来使参数成为一个真正的数组,但我不明白当使用Array.prototype.slice.call(参数);时会发生什么。


当前回答

假设你有:function。apply(thisArg, argArray)

apply方法调用一个函数,传入将绑定到this的对象 和一个可选的参数数组。

slice()方法选择数组的一部分,并返回新数组。

当你调用array。prototype。slice。Apply (arguments,[0])在参数上调用数组切片方法(bind)。

其他回答

它使用slice方法数组have并调用它,它的this是arguments对象。这意味着它会像调用arguments.slice()一样调用它,假设参数有这样一个方法。

创建一个不带任何参数的切片将简单地获取所有元素——因此它只是简单地将元素从参数复制到数组中。

当正常调用.slice()时,底层发生的事情是,这是一个数组,然后它只是迭代该数组,并完成它的工作。

这是如何在.slice()函数数组?因为当你这样做的时候:

object.method();

...对象自动成为this在方法()中的值。所以有:

[1,2,3].slice()

...数组[1,2,3]被设置为.slice()中的this值。


但是如果你可以用别的东西代替这个值呢?只要你替换的东西有一个数值的。length属性,还有一堆数值索引的属性,它就可以工作。这种类型的对象通常称为类数组对象。

.call()和.apply()方法允许您在函数中手动设置this的值。因此,如果我们在.slice()中将this的值设置为一个类似数组的对象,.slice()将假设它正在处理一个数组,并将执行它的任务。

以这个普通对象为例。

var my_object = {
    '0': 'zero',
    '1': 'one',
    '2': 'two',
    '3': 'three',
    '4': 'four',
    length: 5
};

这显然不是一个数组,但如果你可以将它设置为.slice()的This值,那么它就会工作,因为它看起来足够像一个数组,让.slice()正常工作。

var sliced = Array.prototype.slice.call( my_object, 3 );

例如:http://jsfiddle.net/wSvkv/

正如你在控制台看到的,结果是我们所期望的:

['three','four'];

这就是当你将参数对象设置为.slice()的this值时所发生的情况。因为参数有一个.length属性和一堆数值索引,.slice()就像在一个真正的数组上工作一样。

array. prototype.slice.call(参数)是将参数转换为数组的老式方法。

在ECMAScript 2015中,你可以使用Array.from或展开操作符:

let args = Array.from(arguments);

let args = [...arguments];

当正常调用.slice()时,这是一个数组,然后它只是迭代该数组,并完成它的工作。

 //ARGUMENTS
function func(){
  console.log(arguments);//[1, 2, 3, 4]

  //var arrArguments = arguments.slice();//Uncaught TypeError: undefined is not a function
  var arrArguments = [].slice.call(arguments);//cp array with explicity THIS  
  arrArguments.push('new');
  console.log(arrArguments)
}
func(1,2,3,4)//[1, 2, 3, 4, "new"]
// We can apply `slice` from  `Array.prototype`:
Array.prototype.slice.call([]); //-> []

// Since `slice` is available on an array's prototype chain,
'slice' in []; //-> true
[].slice === Array.prototype.slice; //-> true

// … we can just invoke it directly:
[].slice(); //-> []

// `arguments` has no `slice` method
'slice' in arguments; //-> false

// … but we can apply it the same way:
Array.prototype.slice.call(arguments); //-> […]

// In fact, though `slice` belongs to `Array.prototype`,
// it can operate on any array-like object:
Array.prototype.slice.call({0: 1, length: 1}); //-> [1]