我知道它是用来使参数成为一个真正的数组,但我不明白当使用Array.prototype.slice.call(参数);时会发生什么。
当前回答
Array.prototype.slice=function(start,end){
let res=[];
start=start||0;
end=end||this.length
for(let i=start;i<end;i++){
res.push(this[i])
}
return res;
}
当你这样做时:
Array.prototype.slice.call(arguments)
Arguments在slice中变成this的值,然后slice返回一个数组
其他回答
Array.prototype.slice=function(start,end){
let res=[];
start=start||0;
end=end||this.length
for(let i=start;i<end;i++){
res.push(this[i])
}
return res;
}
当你这样做时:
Array.prototype.slice.call(arguments)
Arguments在slice中变成this的值,然后slice返回一个数组
首先,您应该了解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);
// 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]
arguments对象实际上不是Array的实例,也没有任何Array方法。因此,arguments.slice(…)将不起作用,因为arguments对象没有slice方法。
数组确实有这个方法,因为arguments对象与数组非常相似,所以两者是兼容的。这意味着我们可以在arguments对象中使用数组方法。由于数组方法是在考虑数组的情况下构建的,因此它们将返回数组而不是其他参数对象。
为什么使用array。prototype呢?Array是我们用来创建新数组的对象(new Array()),这些新数组被传递方法和属性,比如slice。这些方法存储在[Class]中。原型对象。因此,为了提高效率,我们不通过(new Array()).slice.call()或[].slice.call()来访问slice方法,而是直接从原型中获取它。这样我们就不必初始化一个新数组。
But why do we have to do this in the first place? Well, as you said, it converts an arguments object into an Array instance. The reason why we use slice, however, is more of a "hack" than anything. The slice method will take a, you guessed it, slice of an array and return that slice as a new array. Passing no arguments to it (besides the arguments object as its context) causes the slice method to take a complete chunk of the passed "array" (in this case, the arguments object) and return it as a new array.
/*
arguments: get all args data include Length .
slice : clone Array
call: Convert Object which include Length to Array
Array.prototype.slice.call(arguments):
1. Convert arguments to Array
2. Clone Array arguments
*/
//normal
function abc1(a,b,c){
console.log(a);
}
//argument
function: function abc2(){
console.log(Array.prototype.slice.call(arguments,0,1))
}
abc1('a','b','c');
//a
abc2('a','b','c');
//a