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


当前回答

也许有点晚了,但所有这些混乱的答案是,在JS中使用call()进行继承。 如果我们将其与Python或PHP进行比较,例如,调用分别用作super().init()或parent::_construct()。

这是它的用法的一个例子,阐明了所有:

function Teacher(first, last, age, gender, interests, subject) {
  Person.call(this, first, last, age, gender, interests);

  this.subject = subject;
}

参考:https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance

其他回答

别忘了,这种行为的底层基础是完全集成在js引擎中的类型转换。

Slice只接受object(多亏了已有的参数。Length属性),并在对其执行所有操作后返回数组对象。

如果你试图用INT-value来处理String-method,你可以测试相同的逻辑:

String.prototype.bold.call(11);  // returns "<b>11</b>"

这就解释了上面的表述。

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

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

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

var args = Array.prototype.slice.call(arguments);

也许有点晚了,但所有这些混乱的答案是,在JS中使用call()进行继承。 如果我们将其与Python或PHP进行比较,例如,调用分别用作super().init()或parent::_construct()。

这是它的用法的一个例子,阐明了所有:

function Teacher(first, last, age, gender, interests, subject) {
  Person.call(this, first, last, age, gender, interests);

  this.subject = subject;
}

参考:https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance

首先,您应该了解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);
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返回一个数组