天天看点

Array.prototype.slice.call()如何工作?

本文翻译自:how does Array.prototype.slice.call() work?

我知道它用于使参数成为一个真正的数组,但我不明白使用

Array.prototype.slice.call(arguments)

时会发生什么

#1楼

参考:https://stackoom.com/question/TbpN/Array-prototype-slice-call-如何工作

#2楼

I'm just writing this to remind myself...

我只是写这个来提醒自己......
Array.prototype.slice.call(arguments);
==  Array.prototype.slice(arguments[1], arguments[2], arguments[3], ...)
==  [ arguments[1], arguments[2], arguments[3], ... ]
           

Or just use this handy function $A to turn most things into an array.

或者只是使用这个方便的函数$ A将大多数东西变成一个数组。
function hasArrayNature(a) {
    return !!a && (typeof a == "object" || typeof a == "function") && "length" in a && !("setInterval" in a) && (Object.prototype.toString.call(a) === "[object Array]" || "callee" in a || "item" in a);
}

function $A(b) {
    if (!hasArrayNature(b)) return [ b ];
    if (b.item) {
        var a = b.length, c = new Array(a);
        while (a--) c[a] = b[a];
        return c;
    }
    return Array.prototype.slice.call(b);
}
           

example usage...

示例用法...
function test() {
    $A( arguments ).forEach( function(arg) {
        console.log("Argument: " + arg);
    });
}
           

#3楼

// 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]
           

#4楼

when .slice() is called normally, this is an Array, and then it just iterates over that Array, and does its work.

当.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"]
           

#5楼

First, you should read how function invocation works in JavaScript .

首先,您应该阅读函数调用在JavaScript中的工作原理 。

I suspect that alone is enough to answer your question.

我怀疑只有这一点足以回答你的问题。

But here's a summary of what is happening:

但这里是对正在发生的事情的总结:

Array.prototype.slice

extracts the

slice

method from

Array

's prototype .

Array.prototype.slice

Array

的原型中提取

slice

方法 。

But calling it directly won't work, as it's a method (not a function) and therefore requires a context (a calling object,

this

), otherwise it would throw

Uncaught TypeError: Array.prototype.slice called on null or undefined

.

但是直接调用它是行不通的, 因为它是一个方法(不是一个函数) ,因此需要一个上下文(一个调用对象,

this

),否则它会抛出

Uncaught TypeError: Array.prototype.slice called on null or undefined

The

call()

method allows you to specify a method's context, basically making these two calls equivalent:

call()

方法允许您指定方法的上下文,基本上使这两个调用等效:
someObject.slice(1, 2);
slice.call(someObject, 1, 2);
           

Except the former requires the

slice

method to exist in

someObject

's prototype chain (as it does for

Array

), whereas the latter allows the context (

someObject

) to be manually passed to the method.

除了前者要求

slice

方法存在于

someObject

的原型链中(就像它对

Array

),而后者允许将上下文(

someObject

)手动传递给方法。

Also, the latter is short for:

此外,后者简称:
var slice = Array.prototype.slice;
slice.call(someObject, 1, 2);
           

Which is the same as:

这与以下相同:
Array.prototype.slice.call(someObject, 1, 2);
           

#6楼

Maybe a bit late, but the answer to all of this mess is that call() is used in JS for inheritance.

也许有点晚了,但所有这些混乱的答案是在JS中使用call()进行继承。

If we compare this to Python or PHP, for example, call is used respectively as super().

例如,如果我们将它与Python或PHP进行比较,则call分别用作super()。

init () or parent::_construct().

init ()或parent :: _ construct()。

This is an example of its usage that clarifies all:

这是其用法的一个示例,阐明了所有:
function Teacher(first, last, age, gender, interests, subject) {
  Person.call(this, first, last, age, gender, interests);

  this.subject = subject;
}
           

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

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

继续阅读