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.sliceArray原型中提取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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值