Array.apply(null,obj)的原理是什么?

时间:2019-08-14 14:46:59

标签: javascript arrays ecmascript-6 ecma262

let a = {0: 'a', 1: 'b', length: 2}
Array.apply(null, a) // ['a', 'b']

使用Array构造函数是将类似Array的对象转换为Array的最快方法,例如jsperf

我想弄清楚它是如何工作的,但是我失败了。在ECMAScript-262中,我找不到相应的方法来解释该代码。

为什么Array构造函数接受类似数组的对象可以将其转换为Array。

Difference between Array.apply(null, Array(x) ) and Array(x)

Why does Array.apply(null, [args]) act inconsistently when dealing with sparse arrays?

2 个答案:

答案 0 :(得分:1)

使用apply(),您可以调用一个函数并传递应作为数组对象使用的参数。

所以Array.apply(null, {0: 'a', 1: 'b', length: 2})等同于Array('a','b')

并且可以使用(MDN - Array)构造一个数组:

new Array(element0, element1[, ...[, elementN]])

并且由于数组属于可以在没有new的情况下构造的对象,因此给定的代码将使用这些元素构造一个数组。

答案 1 :(得分:1)

使用Function#apply()时, second 参数采用array-like。类似数组的对象基本上是具有数字键和length属性的对象,但不一定是数组,例如the arguments object is an array-like

该参数将被提供给您调用apply的函数,就好像它是该函数的所有参数一样:

function foo(one, two, three) {
  console.log("one:", one);
  console.log("two:", two);
  console.log("three:", three);
}
//normal invocation
foo("hello", "world", "!");

//.apply using an array-like
foo.apply(null, {0: "nice", 1: "meeting", 2: "you", length: 3});

//.apply using an array
foo.apply(null, ["see", "you", "later"]);

因此,当您调用Array.apply(null, {0: 'a', 1: 'b', length: 2})等效于具有多个参数的调用Array('a', 'b')-using the array constructor时,将根据这些参数生成一个数组:

console.log(Array("a", "b"));

因此,当您在构造函数上调用apply时,您会得到这种行为。

在ES6中,将数组作为第二个参数传递给.apply几乎与使用传播语法相同:

function foo(one, two, three) {
  console.log("one:", one);
  console.log("two:", two);
  console.log("three:", three);
}

const arrayArgs = ["hello", "world", "!"];
foo(...arrayArgs);

但是,这不适用于类似数组的内容:

function foo(one, two, three) {
  console.log("one:", one);
  console.log("two:", two);
  console.log("three:", three);
}

const arrayLikeArgs = {0: "hello", 1: "world", 2: "!", length: 3};
foo(...arrayLikeArgs);