Javascript Array.from()与扩展语法

Javascript Array.from()与扩展语法,javascript,arrays,ecmascript-6,Javascript,Arrays,Ecmascript 6,使用Array.from(document.queryselectoral('div'))或[…document.queryselectoral('div')]之间有什么区别吗 以下是一个例子: let spreadDivArray = [...document.querySelectorAll('div')]; console.log(spreadDivArray); let divArrayFrom = Array.from(document.querySelectorAll('div')

使用
Array.from(document.queryselectoral('div'))
[…document.queryselectoral('div')]
之间有什么区别吗

以下是一个例子:

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

let divArrayFrom = Array.from(document.querySelectorAll('div'));
console.log(divArrayFrom);
console.log()
将记录相同的结果


性能有什么不同吗

不同之处在于,spread允许数组进行扩展。而
from()
创建一个新的数组
.from()
不展开任何内容,它根据提供的数据创建一个新数组;另一方面,spread操作符可以用新属性扩展数组。

使用Babel是查看内部情况的好方法

不过,请注意。确保在Babel中选择了latest,因为默认值是错误的

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

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);
函数_toConsumableArray(arr){if(Array.isArray(arr)){for(vari=0,arr2=Array(arr.length);i
那么,
数组。from
是一个静态方法,即一个函数,而
spread
语法是数组文本语法的一部分。您可以像传递数据一样传递函数,可以调用它们一次、多次或根本不调用。这在
spread
语法中是不可能的,在这方面它是静态的


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

spread元素()仅适用于对象是(即实现
@@iterator
方法)
Array.from()
也适用于类似数组的对象(即具有
length
属性和索引元素的对象),这些对象是不可编辑的。请参见此示例:

const arrayLikeObject={0:a',1:b',长度:2};
//此日志记录['a','b']
log(Array.from(arrayLikeObject));
//这抛出TypeError:arrayLikeObject[Symbol.iterator]不是函数

log([…arrayLikeObject])如果输入是可输入的,则它们会执行完全相同的操作

然而,基于基准测试,对于集合,扩展操作符似乎表现得更好

let set=new set();
for(设i=0;i<10000;i++){
set.add(Math.random());
}
让tArrayFrom=window.performance.now()
设arr=Array.from(set)
console.log(“Array.from():”,window.performance.now()-tArrayFrom+“ms”)
//在大多数跑步中速度略快:
让tSpread=window.performance.now()
设arr2=[…设置];

console.log(“Spread syntax:,window.performance.now()-tSpread+“ms”)
我需要澄清每个人的答案:

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

spread运算符的优点是它支持
对象
。演出IDKT要找出是否存在任何性能差异,请运行基准测试。根据您是在本机ES6环境中还是正在传输到ES5,结果可能会有很大的不同。主要区别在于
Array.from
与未实现迭代器协议的类似数组的对象(即
Symbol.iterator
)一起工作。即使有了ES6和新的浏览器规范,它们也越来越少。嗯,数组文字也总是创建一个新的数组……我不确定我是否误解了你的措辞,但你是在建议spread操作符变异数组而不是创建一个新的数组吗?@Bergi Well spread操作符不创建数组。OP示例中的数组创建是通过排列操作符周围的方括号完成的。啊,好的,我只是想确定你的意思是正确的。如果您说“扩展数组文字”而不是“扩展数组”,可能会有所帮助,因为它不会对任意数组进行操作。为了澄清:
…foo
语法只是扩展(扩展)所有数组值,就好像它们是分开的、逗号分隔的参数一样。它周围的
[]
创建了一个新阵列。因此,
[…foo]
将创建一个新数组,并通过像数组构造函数参数一样分散所有数组元素来填充它,并对每个元素进行完整复制。而
Array.from(foo)
将使用输入变量创建一个新数组,而且速度更快,因为它创建了一个浅拷贝(这更快)。
[]如果节点列表不可concatspreadable,concat
似乎不起作用?这是Babel输出吗?
这是Babel输出吗
事实上,我刚刚将代码复制到了babeljs.io,有没有一个例子?也许Babel会在需要时进行其他转换。当然,这只是针对这个特定的案例进行测试。babeljs.io repl有一些奇怪的选项,它不太可靠。使用
[].concat
是不正确的简化