我需要澄清一下使用展开运算符时会发生啥

Posted

技术标签:

【中文标题】我需要澄清一下使用展开运算符时会发生啥【英文标题】:I need some clarification on what happens when I use the spread operator我需要澄清一下使用展开运算符时会发生什么 【发布时间】:2019-04-24 13:46:13 【问题描述】:

当我在 NodeList 上使用扩展运算符时:

[...document.querySelectorAll("div")]

是吗:

    创建一个新数组 将document.querySelectorAll("div")转换成数组 将document.querySelectorAll("div") 的值解压到数组字面量([])中

【问题讨论】:

扩展运算符创建当前可迭代对象的单级深层副本。这有一些限制。请参阅developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 它将输出分配给新内存,您可以为其指向一个变量。它与 map/reduce/sort 搭配得很好,因为它不会修改原始对象。 【参考方案1】:

你得到的 NodeList 是可迭代的(在现代环境中),所以效果

[...document.querySelectorAll("div")]

与从普通数组传播相同。它实际上在做同样的事情

Array.from(document.querySelectorAll("div"))

所以是的,创建了一个新数组,然后将查询的元素迭代复制到新数组中。不需要从 NodeList 构建中间数组,因为它已经是可迭代的。你最终得到了一个普通的数组。

任何数组初始化器使用扩展语法创建一个新数组,就像任何传统使用数组初始化器一样;这就是重点。)

注意... 严格来说不是一个运算符;它不是表达式语法的一部分。 (好吧,因为您可以将数组初始化器和对象初始化器语法视为整个表达式语法的一部分,但它仍然不是运算符。)但是不能将其称为运算符是很笨拙的,所以我我个人很同情。

【讨论】:

感谢您花时间和精力回答这个问题,虽然我必须说,仍然没有足够的 jQuery :)【参考方案2】:

展开运算符允许您做不同的事情 (CHECK HERE)。

在您的情况下,您正在创建一个包含来自 document.querySelectorAll("div") 的所有元素的新数组

const arr = [...document.querySelectorAll("div")];

    console.log(arr.length);
    console.log(typeof(arr));
<div>
  <p>first div</p>
  <div>
    <p>second nested div</p>
  </div>
</div>

【讨论】:

【参考方案3】:

展开运算符不会将数据转换为数组。它正在查看您提供给它的可迭代对象的自己的和可枚举的属性

然后它将它们复制到您告诉它的位置:

在数组中:[...obj]

在一个对象中:...obj

在参数中:func(...obj)


关于扩展运算符的真正精彩指南:https://dmitripavlutin.com/object-rest-spread-properties-javascript/

const set = new Set();

set.add('a');
set.add('b');

console.log(typeof set);

console.log(...set);
console.log(...['a', 'b']);

【讨论】:

以上是关于我需要澄清一下使用展开运算符时会发生啥的主要内容,如果未能解决你的问题,请参考以下文章

当你在同一个 Perl 语句中有一个条件运算符和一个后缀条件时会发生啥?

当我对具有复制构造函数但没有赋值运算符的对象进行赋值时会发生啥?

在 java 澄清中使用 += 和三元运算符

vuex中使用对象展开运算符

C 逗号运算符

ES6展开运算符应用于数组拷贝的机制