当前位置: 首页 > 知识库问答 >
问题:

为什么“new Date().toString()”在给定Javascript运算符优先级的情况下有效?

糜鸿风
2023-03-14

MDN指出,Javcript中有两个运算符具有最高的优先级:

  • 左关联成员运算符:foo.bar
  • 右关联的新运算符:new Foo()

我通常会显式地将两者分开:(newdate())。toString()
但我经常看到这两种方法结合在一起:newdate()。toString()

根据这个答案,第二种方法起作用的原因是,当两个操作符的优先级相等时,第二个操作符的结合性才是重要的。在这种情况下,成员运算符是左关联的,这意味着首先计算new Date()

然而,如果是这样的话,那么为什么newdate。toString()失败?毕竟,newdate只是newdate()的语法糖。上面的论点说它应该有效,但显然不行。

我错过了什么?

共有2个答案

澹台景辉
2023-03-14

我是写“用不同关联性和相同优先级的相邻运算符消除表达式歧义”的问题和答案的人,当我写这篇文章时,我脑子里没有JavaScript。

我考虑的语言是Haskell,这是一种函数式编程语言。这种语言中的运算符只是函数,更容易推理。然而,我写答案的方式没有假设任何编程语言。

另一方面,JavaScript是一种传统的编程语言,JavaScript中的表达式是基于复杂的解析规则来消除歧义的,这些解析规则与Haskell使用的解析规则非常不同。

特别是JavaScript解析规则似乎很贪婪。例如,以您的第一个示例为例:

new Date().toString()

此处Date之后的函数调用屏蔽了成员操作员发出的Date。因此,贪婪的new仍然只能在Date而不是Date()上操作。toString。因此,我们有:

((new Date()).toString)()

在第二个例子中,我们有:

new Date.toString()

这里在Date之后没有函数调用来屏蔽成员操作符。因此,new,贪婪地在表达式日期操作。toString。因此,我们有:

(new (Date.toString))()

@thg435的回答支持这一说法。重点是,我讨论的是一个正式的系统,它与JavaScript解析器实现的系统完全不同。我所讨论的正式系统将运算符和操作数都视为第一类值。

朱兴安
2023-03-14

语法是

MemberExpression :
    PrimaryExpression
    FunctionExpression
    MemberExpression [ Expression ]
    MemberExpression . IdentifierName
    new MemberExpression Arguments

new foo(). bar不能被解析为new(foo(). bar),因为foo(). bar不是Member表达式。此外,出于同样的原因,new foo()不能解析为new(foo())。相反,newfoo.bar被解析为new(foo.bar),因为foo.bar是一个有效的Member表达式(解释(new foo). bar是不可能的因为语法贪婪)。

即,优先规则是:点跳动新,新跳动调用(括号)。

.  -> new -> ()

此外,直接查看语法可以解开将newfoo转换为newfoo()的语法糖分。这只是一种新的表达方式← 新表达← 新PrimaryExpression:

NewExpression :
    MemberExpression
    new NewExpression
 类似资料:
  • 问题内容: 我似乎无法与三元运算符结合使用此代码的第一部分(+ =)。 我认为这段代码的工作方式如下: 但这是不正确的,因为这会导致控制台出现错误。 所以我的问题是我应该如何正确插入此代码? 问题答案: h.className = h.className + (h.className ? ‘ error’ : ‘error’) 您希望操作员为之工作,最好对此有所具体。 当然,不应有任何伤害 ,但这

  • 问题内容: 在此代码中: 我所期望的 由于最里面的括号的优先级,将执行First 。因此,值将为11,此表达式的值将为15。然后将被执行。所以12 * 15 =180。所以z = 180 我得到了什么 z = 176 这意味着VM从左到右不遵循操作员优先级。那么我对运算符优先级的理解是错误的吗? 问题答案: 表达式( y *(y + 5)); 将被放置在这样的堆栈中: 结果将按照该顺序执行 该表达

  • 从高到低顺序如下: ^ not - (一元运算) * / + - ..(字符串连接) < > <= >= ~= == and or

  • 问题内容: 我正在尝试测试2个线程,一个线程具有较高的优先级,而另一个线程具有较低的优先级。 根据我的结果,有时低优先级线程速度更快,这怎么可能?我已经通过增加每个线程内的click变量来测试了不同优先级的线程。我也增加和减少了睡眠时间,但是什么也没有。 由于我是在没有后台运行繁重程序的情况下进行测试的,因此我决定在运行高清影片的情况下进行测试,但仍然没有真正的变化,线程的速度始终相同。 我的电脑

  • 问题内容: 下面的代码打印出“ 3”,而不是您期望的“ 4”。 我懂 后缀增量发生在加载“ a”的值之后。(见下文)。 我不太明白是为什么。后缀++的运算符优先级高于+,因此它不应该首先执行吗? 问题答案: Postfix 递增变量的值,并 返回递增之前的值 。因此,在您的示例中,返回值将为,当然将为,然后将其赋给。在分配时,已经将to 的值增加了(由于优先),因此将覆盖该增加的值。

  • 本文向大家介绍浅谈JavaScript中运算符的优先级,包括了浅谈JavaScript中运算符的优先级的使用技巧和注意事项,需要的朋友参考一下 运算符优先级 JavaScript中的运算符优先级是一套规则。该规则在计算表达式时控制运算符执行的顺序。具有较高优先级的运算符先于较低优先级的运算符执行。例如,乘法的执行先于加法。 下表按从最高到最低的优先级列出JavaScript运算符。具有相同优先级的