是...... foo是运算符还是语法?

时间:2017-07-05 19:49:51

标签: javascript ecmascript-6 language-lawyer spread-syntax

我听说...同时提到了 语法'和运营商',后者更受欢迎。相关MDN documentation的网址表明它最初被称为spread 运算符,但后来更改为spread语法,而MDN's list of operators并未提及它。

谷歌似乎建议运营商一词更受欢迎和接受,Microsoft documentationes6-features.org这样的网站就是这样说的。

哪个术语在ECMAScript的上下文中最正确,如果有的话,为什么?那么数组解构赋值呢?

1 个答案:

答案 0 :(得分:1)

语法的其他用法

主要答案中未涵盖其他众多的传播/休息语法用法。它们包括:

  • 功能参数中的休息语法
  • 数组和对象 1 解构分配
  • 对象文字 1
  • 中的对象传播语法

其余语法

扩展语法的用法,通常称为 rest 语法,用于函数的参数中的可变数量的参数。这与spread参数不同,传播参数用于根据iterable的元素将参数传递给函数 call 。例如:

function add(...addends) {
  …
}

此处,rest函数用于函数add以接收标识符addends中参数的 rest 。这似乎评估为一个单数值,因为addends是传递参数的数组,但是如果我们尝试了怎么办:

function foo(...[bar, baz]) {
  …
}

在这里,barbaz都将被赋予与传递的第一个和第二个参数相对应的值 - 因此,这并不总是计算为一个值。根本问题是第一个例子中的...addends和第二个例子中的...[bar, baz]实际上根本没有评估到一个值 - 它只是在为参数赋予参数数组的操作中使用。因此,它的语法是允许函数的可变数量的参数,而不是操作符。

解构分配

array destructuring assignment期间也可以使用扩展语法,并且在语言规范中实际上称为rest元素(因为在解构时使用时,它会得到结构化可迭代的其余 )。可以提出令人信服的论点,因为这看起来像是一个运算符:

const [...bar] = [1, 2, 3];

它像前缀一元运算符一样使用。在这里,bar评估为[1, 2, 3] - 这是一个单一值。但这并不总是发生,例如:

const [first, ...[second, third]] = [1, 2, 3];

此处,firstsecondthird分别评估为1,2和3。但...[second, third]分配给两个标识符,而不是一个标识符,并且不评估为单数值,而是两个。就像休息语法一样,潜在的问题是第一个示例中的...bar和第二个中的...[second, third]实际上并没有评估到一个值 - 它只是使用了在任务期间。因此,它不是一个操作员 2 ,只是新的sytax来帮助解包价值。

对象扩展语法

传播语法的最终用法是在对象文字中,通常称为“对象传播属性”,其中目标对象自己的可枚举属性被传播到另一个,例如:

const foo = { ...bar };

这不是运算符,就像数组传播语法不是运算符一样。概念是相同的,而不是数组中的索引和元素,bar的可枚举键和值传播到foo。这里,bar属性的集合被传播 - 不只是一个单独的值,因此它不符合运算符的定义。

1 Object rest/spread properties目前处于ECMAScript的第3阶段提案中,很可能会在不久的将来添加

2 除了语义之外,解构赋值作为运算符的另一个问题是the language specification将其定义为补充语法 - 而不是补充操作员,这是理所当然的。它不是独立的,因为这不起作用:

const ...bar = [1, 2, 3, 4];

语境的语法,对象文字和作为左侧表达式的数组文字只允许使用它。它也是改进左手侧表达式的解释的语法。同样,这是向语言添加新语法的扩展,是对现有语法的改进。这再次证实了规范的论点。