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


当前回答

通常,调用

var b = a.slice();

将数组a复制到b中。然而,我们不能

var a = arguments.slice();

因为参数没有slice作为方法(它不是一个真正的数组)。

Array.prototype.slice是数组的slice函数。.call运行这个slice函数,并将this值设置为参数。

其他回答

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

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

let args = Array.from(arguments);

let args = [...arguments];

正如MDN所指出的,这是因为

arguments对象不是数组。它类似于数组,但是 除了长度以外,没有任何数组属性。例如,它确实如此 没有pop方法。然而,它可以转换为一个真正的数组:

这里我们是在原生对象Array上调用slice,而不是在它的实现上调用slice,这就是为什么要使用额外的.prototype

var args = Array.prototype.slice.call(arguments);
// 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]

首先,您应该了解JavaScript中的函数调用是如何工作的。我想这就足以回答你的问题了。但下面是正在发生的事情的总结:

slice从Array的原型中提取slice方法。但是直接调用它不会起作用,因为它是一个方法(不是一个函数),因此需要一个上下文(一个调用对象,这个),否则它会抛出Uncaught TypeError: Array.prototype.slice调用null或undefined。

call()方法允许你指定一个方法的上下文,基本上使这两个调用等价:

someObject.slice(1, 2);
slice.call(someObject, 1, 2);

除了前者要求slice方法存在于someObject的原型链中(就像它对Array所做的那样),而后者允许将上下文(someObject)手动传递给该方法。

后者也是:

var slice = Array.prototype.slice;
slice.call(someObject, 1, 2);

也就是:

Array.prototype.slice.call(someObject, 1, 2);

当正常调用.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"]