Array.from()vs spread语法

时间:2016-11-11 12:38:11

标签: javascript arrays ecmascript-6

使用Array.from(document.querySelectorAll('div'))[...document.querySelectorAll('div')]

之间是否存在一些差异?

这是一个例子:

let spreadDivArray = [...document.querySelectorAll('div')];
console.log(spreadDivArray);

let divArrayFrom = Array.from(document.querySelectorAll('div'));
console.log(divArrayFrom);

console.log()会记录相同的结果。

有任何性能差异吗?

6 个答案:

答案 0 :(得分:30)

传播元素it's not an operator)仅适用于iterable的对象(即实现@@iterator方法)。 Array.from()也适用于不可迭代的类数组对象(即具有length属性和索引元素的对象)。见这个例子:



const arrayLikeObject = { 0: 'a', 1: 'b', length: 2 };

// This logs ['a', 'b']
console.log(Array.from(arrayLikeObject));
// This throws TypeError: arrayLikeObject[Symbol.iterator] is not a function
console.log([...arrayLikeObject]);




另外,如果您只想将某些内容转换为数组,我认为使用Array.from()会更好,因为它更具可读性。例如,当您想要连接多个数组(['a', 'b', ...someArray, ...someOtherArray])时,Spread元素很有用。

答案 1 :(得分:6)

嗯,Array.from是一个静态方法,即一个函数,而spread语法是数组文字语法的一部分。您可以像数据一样传递函数,您可以调用一次,多次或根本不调用它们。使用spread语法是不可能的,这在这方面是静态的。

@ nils已经指出的另一个区别是Array.from也适用于类似数组的对象,它们不实现可迭代协议。另一方面,spread需要迭代。

答案 2 :(得分:2)

不同之处在于,传播允许阵列扩展。而from()创建数组。 .from()不会扩展任何内容,它会根据提供的数据创建一个新数组;另一方面,扩展运算符可以扩展具有新属性的数组。

答案 3 :(得分:0)

如果输入是可迭代的,则它们将执行完全相同的操作。

但是,基于基准,散布运算符对于Set似乎表现更好。

https://jsben.ch/5lKjg

let set = new Set();
for (let i = 0; i < 10000; i++) {
    set.add(Math.random());
}


let tArrayFrom = window.performance.now()

let arr = Array.from(set)

console.log(window.performance.now()-tArrayFrom)


// slightly faster in most of the runs:
let tSpread = window.performance.now()

let arr2 = [...set];

console.log(window.performance.now()-tSpread)

答案 4 :(得分:0)

我需要澄清每个人的答案:

  • ...foo 语法只是扩展(扩展)所有数组值,就好像它们是单独的、逗号分隔的参数一样。它的传播很浅。任何素数(数字、字符串等)都被复制,任何复杂的值(对象)都被引用。
  • 它周围的 [] 用于创建新数组。
  • 所以 [...foo] 将创建一个新数组,并通过对所有数组元素进行浅复制来填充它,就好像它们是数组构造函数参数一样,这些参数依次获取所有这些复制的元素并将它们放入新数组中。
  • Array.from(foo) 将使用输入变量创建一个新数组,但速度要快得多,因为它只创建一个浅拷贝(这更快)。所以它需要精确的输入,并将每个变量/引用放入新数组中。
  • 使用Array.from()

答案 5 :(得分:-1)

使用Babel是了解内部发生情况的好方法。

然而抬起头来。确保在Babel中选择最新,因为默认是错误的。

使用上面的示例,这是输出。

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var spreadDivArray = [].concat(_toConsumableArray(document.querySelectorAll('div')));
console.log(spreadDivArray);

var divArrayFrom = Array.from(document.querySelectorAll('div'));
console.log(divArrayFrom);