当前位置: 首页 > 面试题库 >

是传播“语法”还是传播“运算符”?

漆雕育
2023-03-14
问题内容

我听说过...这两种语言都称为“传播语法”和“传播算子”,后者更为流行。有关MDN文档的URL表明,它最初被称为扩展运算符,但后来更改为扩展语法,而MDN的运算符列表未提及它。

Google似乎建议使用术语“运营商”来普及和接受,例如Microsoft文档和[es6-features.org]等网站都将其称为“运营商”。

在ECMAScript的上下文中,哪一个术语最正确(如果有),为什么?数组销毁分配又如何呢?


问题答案:

它不是运算符。

从所有意义上说,这不是一个。自引入以来,这一直是一个巨大的误解,尽管受到了大众的欢迎-这不是一个错误,并且有一些客观要点:

  • 它不符合运算符的定义
  • 不能用作运算符
  • 语言规范暗示它不是运算符

应该提到的是,扩展语法具有不同的“风味”,在不同的上下文中使用,并且在使用相同的标点符号时通常以不同的名称进行引用。传播语法基本上是...标点符号应用的总称,详细介绍了所有用法和名称。关于这些个人用途的更多解释在补充答案中给出。

什么是运算符?

从语义上讲,在ECMAScript上下文中,运算符只是内置函数,这些函数接受参数并求值为单个值
-以前缀,中缀或后缀表示法编写,通常使用诸如+或的符号名/

简而言之,以某种方式评估涉及运算符的表达式,结果值可能只是一个值(一个r值),或者可能是一个允许赋值的对象(一个l值)。

例如,+运算符将得出一个值为2的值,它是一个右侧表达式,.运算符将得出一个对象,该对象允许赋值,例如foo.bar左侧表达式。

在表面上,...标点符号1看起来像是前缀一元运算符:

const baz = [foo, ...bar];

但是该论点的问题在于,...bar它的求值结果不是奇异的。它bar逐一散布了iterable 的元素。传播参数也是如此:

foo(...bar);

在这里,从iterable foo接收单独的参数bar。它们是传递给的单独值foo,而不仅仅是一个值。它不符合运算符的定义,因此不是一个。

为什么它不是运算符

需要指出的另一点是,运算符应独立并且返回单个值。例如:

const bar = [...foo];

如前所述,这很好。当您尝试执行此操作时会出现问题:

const bar = ...foo;

如果将扩展语法用作运算符,则后者会很好用,因为运算符将表达式评估为单个值,但是扩展则不会,因此失败。扩展语法和扩展参数仅在数组和函数调用的上下文中起作用,因为这些结构会接收由扩展数组元素或参数提供的多个值。评估多个值超出了操作员的能力范围。

标准怎么说?

ECMAScript 2015语言规范的第12.5至§12.15节中列出了运算符的完整列表...,其中未提及引入的规范...。也可以推断出它不是运算符。下面描述了此答案中提到的两种主要情况,其中在函数中使用了扩展语法,分别是函数调用(扩展参数)或数组文字(扩展语法):

ArrayLiteral :
[ Elisionopt ]
[ ElementList ]
[ ElementList , Elisionopt ]

ElementList :
Elisionopt AssignmentExpression
Elisionopt SpreadElement
ElementList , Elisionopt AssignmentExpression
ElementList , Elisionopt SpreadElement

Elision :
,
Elision ,

SpreadElement :
... AssignmentExpression

对于函数调用:

CallExpression :
  MemberExpression Arguments

Arguments :
  ( )
  ( ArgumentList )

ArgumentList :
  AssignmentExpression
  ... AssignmentExpression
  ArgumentList , AssignmentExpression
  ArgumentList , ... AssignmentExpression

在这些作品中,可以得出一个结论:传播的“经营者”不存在。如前所述,运算符应该是独立的,const bar = ...foo并且应评估为一个单一值。该语言的语法阻止了这种情况,这意味着散布语法从来都不是独立的。它是 数组初始化程序和函数调用的扩展,是它们语法的扩展。

为什么传播“语法”?

语法,由Wikipedia定义:

在计算机科学中,计算机语言的语法是一组规则,这些规则定义了符号的组合,这些符号被认为是该语言中结构正确的文档或片段。

语法基本上是语言的“形式”,是控制有关代码外观和代码编写方式的合法性或不合法性的规则。在这种情况下,ECMAScript的语法专门将...标点符号定义为仅在函数调用和数组文字中作为扩展出现这是一个规则,用于定义...foo被认为合法的符号()的组合,因此其语法类似于箭头函数(=>)的作用方式不是运算符,而是语法2。

呼叫...接线员是错误的说法。运算符是一个内置函数,它接受参数(操作数),并且采用前缀,中缀或后缀表示法的形式,并且其计算结果恰好是一个值。...,虽然满足前两个条件,但不满足最后一个条件。...而是语法,因为它是在语言的语法中明确定义的。因此,“散布算子”在客观上更正确地称为“散布语法”。

1术语“标点符号”是指ECMAScript2015及更高版本规范中的标点符号。这些符号包括语法组件和运算符,并且是语言的标点符号。...是标点符号本身,但术语“扩展语法”是指标点符号的整个应用程序。

2 =>本身就是一个 标点符号,...但是我具体要指的是箭头函数语法,即=>标点符号((…) => { … })的应用,就像传播语法_ 指的是...标点符号的应用一样。



 类似资料:
  • 问题内容: 考虑以下示例代码 在这里,价值和是完全相同且等于 ,所以, 两者之间到底有什么区别? 哪一个效率更高?为什么? 传播语法的确切用途是什么? 您是否不认为以正式的广泛语言引入这些小捷径可能会留下一些未被注意的错误,我的意思是要么根本没有必要,要么我没有意识到确实需要这样做。 问题答案: 在给出的示例中,两者之间基本上没有区别 是显著更有效:http://jsperf.com/spread

  • 1.算法简介 AP(Affinity Propagation)通常被翻译为近邻传播算法或者亲和力传播算法,是在2007年的Science杂志上提出的一种新的聚类算法。AP算法的基本思想是将全部数据点都当作潜在的聚类中心(称之为exemplar),然后数据点两两之间连线构成一个网络(相似度矩阵),再通过网络中各条边的消息(responsibility和availability)传递计算出各样本的聚类

  • 问题内容: 我不确定我在这里使用的词汇,如果我错了,请指正。 在Javascript中,我有以下代码: 如您所见,调用时,我可以使用spread运算符将参数“转换”为。 现在,我正在尝试使用Java做同样的事情。 假设我有一堂课: 现在我想打电话给: 我想使用类似的方法来代替。 我看到这在函数的声明中是可行的,但我不想更改这种函数的实现。 问题答案: Java语言不提供操作员来执行此操作,但是其类

  • 前面几节里我们使用了小批量随机梯度下降的优化算法来训练模型。在实现中,我们只提供了模型的正向传播(forward propagation)的计算,即对输入计算模型输出,然后通过autograd模块来调用系统自动生成的backward函数计算梯度。基于反向传播(back-propagation)算法的自动求梯度极大简化了深度学习模型训练算法的实现。本节我们将使用数学和计算图(computationa

  • 问题内容: 什么是异常传播?我尝试使用Google,但找不到满意的结果。最好用Java来解释这一点。 问题答案: 令人惊讶的是,在Java教程页面中有关exception的解释。 异常从一个方法传播到另一个方法,直到调用被捕获为止。因此,如果调用,调用,调用,并且如果抛出异常,则除非这些方法之一捕获到该异常,否则该异常将从d传播到c到b传播到a。

  • 问题内容: 在React文档中给出以下示例代码: 我做了一些调查,最终得出的结果是: 进而得出。 但是我想知道的是,为什么我不能这样做: 我看不出点差运算符的含义是什么。 问题答案: 这有助于使您的代码更简洁-由于是对象,所以散布运算符会将传入的对象的 属性 应用到组件中。因此,该Component的属性a 的值为,而a 的值为。 它将与以下内容相同: 短一点