Array.from()vs spread语法

jot*_*ejv 40 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);
Run Code Online (Sandbox Code Playgroud)

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

有任何性能差异吗?

Mic*_*ski 42

Spread 元素(它不是运算符)仅适用于可迭代的对象(即实现@@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]);
Run Code Online (Sandbox Code Playgroud)

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

  • 虽然我同意Array.from()是实现此目标的一种非常易读的方式,但我觉得扩展元素语法`... arrayLikeObject`对于人们来说可读性相同(或更是如此)。 (3认同)
  • 还请注意,传播语法(`... arrayLikeObject`)要短得多。有时这可能是一个因素,尽管可能并非如此。 (2认同)
  • 警告:数字参数,例如 `var i = 5; Array.from(i)` 结果为 `[]`,其中 `var i = 5; [i]` 结果为 `[5]` (2认同)

小智 8

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

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

  • “Array.from 也适用于类似数组的对象,这些对象不实现可迭代协议”——你能举一个这样的对象的例子吗? (2认同)

Jam*_*lly 6

区别在于 spread允许扩展...数组,而创建一个新数组Array.from()

\n

在您的示例中,[...x]通过使用扩展语法将现有数组扩展为数组文字语法 \xe2\x80\x93 来创建一个新数组,括号是实际执行数组创建位的内容。这些括号可以与任意数量的其他语法交换以实现其他结果(例如扩展到函数参数、对象、使用多个扩展来连接数组)[]foo(...x){...x}[...x, ...y]等)。

\n

.from()从不扩展任何内容,它总是根据提供的数据创建一个新数组。

\n

  • 好吧,数组文字也总是创建一个*新*数组...... (22认同)
  • **澄清一下:** `...foo` 语法只是扩展(扩展)所有数组值,就好像它们是单独的、以逗号分隔的参数一样。它周围的“[]”是创建新数组的内容。因此,“[...foo]”将创建一个新数组,并通过传播所有数组元素来填充它,就好像它们是数组构造函数参数一样,并对每个元素进行完整复制。而 `Array.from(foo)` 将使用输入变量创建一个新数组,并且速度要快得多,因为它创建了一个浅拷贝(这是更快的)。 (5认同)
  • 我不确定我是否只是误解了您的措辞,但是您是否建议扩展运算符改变数组而不是创建一个新数组? (4认同)
  • @Bergi 好吧,扩展运算符不会“创建”数组。OP 示例中的数组创建是通过展开运算符周围的方括号完成的。 (4认同)
  • 啊,好吧,我只是想确定你的意思是正确的。如果您说“扩展数组文字”而不是“扩展数组”,也许会有所帮助,因为它不能对任意数组进行操作。 (4认同)
  • @MitchMcMabers 他们都是浅拷贝。说 spread 是“完整副本”是不正确的。 (4认同)