ECMAScript 文档中的 SpreadElement 是啥?和 MDN 的 Spread 语法一样吗?

Posted

技术标签:

【中文标题】ECMAScript 文档中的 SpreadElement 是啥?和 MDN 的 Spread 语法一样吗?【英文标题】:What is SpreadElement in ECMAScript documentation? Is it the same as Spread syntax at MDN?ECMAScript 文档中的 SpreadElement 是什么?和 MDN 的 Spread 语法一样吗? 【发布时间】:2016-09-06 05:23:54 【问题描述】:

ECMAScript specification 描述了SpreadElement

SpreadElement[Yield]:
...AssignmentExpression[In, ?Yield]

这个和Spread syntax一样吗

Spread 语法允许在预期有零个或多个参数(对于函数调用)或元素(对于数组字面量)的地方扩展诸如数组表达式或字符串之类的可迭代对象,或者在需要扩展对象表达式的地方期望零个或多个键值对(用于对象文字)。

语法

对于函数调用:

myFunction(...iterableObj);

对于数组字面量:

[...iterableObj, 4, 5, 6]

在MDN 文档中描述?

SpreadElement 和,或,传播语法的用例是什么;如果SpreadElement和spread语法不同,具体在哪些方面有区别?

【问题讨论】:

对于函数调用,我个人会说它的 REST 参数而不是扩展运算符。然而,它们都服务于几乎相同的目的和实现方式。 @choz: 嗯,如果我们想要准确的话,应该在调用中传播,在定义中休息:x = f(a, ...b) 传播 bfunction f(a, ...b) 将其余参数收集到 @ 987654337@。与数组相同:在文字中 x = [a, ...b] 它是传播的,在解构赋值 [a, ...b] = x 它是休息。 @Amadan 在x = f(a, ...b) 中,b 必须是一个可迭代对象。我想说这仍然称为spread。而function f(a, ...b),这使得b 必须排在最后,并且能够包含其余参数。所以,我称之为Rest parameters @choz:我想你刚才说的正是我所做的:P 是的,重点是spread syntax is not an "operator" 【参考方案1】:

术语“扩展运算符”是一种“伞形术语”,指的是 ES6 中的各种语法结构,它们看起来都像 ...x。 MDN 也是如此。

但是,这是误导,因为... 不是运算符(至少在 ECMAScript 规范使用术语“运算符”的意义上不是)。它不会生成可用于进一步计算的值。我宁愿将它与其他标点符号进行比较,例如 ,;(它们也有一定的相关性,但在不同的上下文中具有不同的含义)。

术语“扩展运算符”可以指:

Spread element, var arr = [a, b, ...c];:展开元素将可迭代 (c) 扩展为新数组。相当于[a,b].concat(c)

Rest element, [a, b, ...c] = arr;:在解构内部,... 构造具有相反的效果:它将剩余元素收集到一个数组中。这里的例子等价于

a = arr[0];
b = arr[1];
c = arr.slice(2);

(请注意,这只是一个近似值,因为解构适用于任何可迭代的值,而不仅仅是数组)

fun(a, b, ...c):这个构造doesn't actually have a name in the spec。但它的工作原理与展开元素非常相似:它将一个可迭代对象扩展为参数列表。 相当于func.apply(null, [a, b].concat(c))

缺乏正式名称可能是人们开始使用“spread operator”的原因。我可能会称之为“传播论点”。

Rest parameter: function foo(a, b, ...c):与 rest 元素类似,rest 参数收集传递给函数的剩余参数,并使它们在c 中作为数组可用。 ES2015 实际上规范使用术语BindingRestElement 来指代这个结构。

相关问题:

Spread operator vs Rest parameter in ES2015/es6 Using spread operator multiple times in javascript?

:如果我们非常迂腐,我们甚至必须区分变量声明 (var [a, b, ...c] = d;) 和简单赋值 ([a, b, ...c] = d;),根据规范。

【讨论】:

顺便说一句,对于“... 不是操作员”部分,我为此创建了一个 CW 规范(如果您还没有看过):***.com/q/44934828/5647260 来解释一下更多细节,尽管晚了一年。【参考方案2】:

SpreadElement 只是 ES6 语法中的一个名称,用于在数组字面量中传播“运算符”及其参数:

SpreadElement[Yield]:
    ... AssignmentExpression[In, ?Yield]

所以,[a, b, ...c] 中的SpreadElement...c;传播“操作员”是...。 (吓唬人的引号,因为它不是一个真正的运算符,就像- 一样。)

函数调用中使用的语法规则的名称会有所不同,因为它是不同的语法上下文(它只是ArgumentList 的一种)。

【讨论】:

"SpreadElement 只是 ES6 语法中省略运算符的一个名字" 什么是“省略运算符”? 不,SpreadElement 是 ES6 规范中的语法规则,正如我在上面解释的,它不仅仅包含 ... 运算符。而 MDN 将... 称为“操作员”,因为上下文中的含义很清楚,只有学究才会坚持使用syntactic construct 或其他内容。 你在拖钓吗? “为什么 MDN 使用术语运算符?”上面回答:“MDN 将... 称为'操作员',因为上下文中的含义很清楚,只有学究才会坚持句法构造或其他东西”。 “SpreadElement 还涵盖什么?”上面回答:“[a, b, ...c] 中的SpreadElement...c;传播“运算符”是...”。 “什么是‘学究’?”找一本字典。 @guest271314—ECMA-262 是语言规范,因此它是 权威。 MDN 是一个任何人都可以贡献的公共 wiki,它不是任何事情的权威。对于记录(和学究),... 是构成 SpreadElement 一部分的punctuator @guest271314:您可能想看看this deleted question 的cmets,了解... 令牌如何构成运算符。

以上是关于ECMAScript 文档中的 SpreadElement 是啥?和 MDN 的 Spread 语法一样吗?的主要内容,如果未能解决你的问题,请参考以下文章

摘录ECMAScript官方文档中重要的两段话

ES8(ECMAScript 2017) 语言规范发布,附ES6,ES7,ES8规范文档下载

ECMAScript

JavaScript的3大组成部分&&ECMAScript函数&&闭包

ECMAScript 6 学习笔记--编译环境搭建

Node中的JavaScript和浏览器中的JavaScript的区别