感叹号的优先级是否低于Javascript中的方法调用和属性访问?

感叹号的优先级是否低于Javascript中的方法调用和属性访问?,javascript,Javascript,当使用感叹号否定表达式时,为了安全起见,我总是使用括号。。。但是我做了一些测试,看起来感叹号操作符的优先级很低,以至于在大多数用例中不需要括号,即函数调用和属性访问: !(myFunction()); // can be replaced by !myFunction() !(myObject.myProperty); // can be replaced by !myObject.myProperty 对吗?无论如何,使用括号是一种好的做法吗?对于运算符优先级(任何语言的基本部

当使用感叹号否定表达式时,为了安全起见,我总是使用括号。。。但是我做了一些测试,看起来感叹号操作符的优先级很低,以至于在大多数用例中不需要括号,即函数调用和属性访问:

!(myFunction());        // can be replaced by !myFunction()
!(myObject.myProperty); // can be replaced by !myObject.myProperty

对吗?无论如何,使用括号是一种好的做法吗?

对于运算符优先级(任何语言的基本部分)之类的内容,最好的办法通常是查阅文档,例如

而不是做一堆测试。测试对于验证运行时行为很重要,但尝试根据经验确定运算符优先级可能会变得复杂:有很多运算符

为了真正理解操作符优先级是如何工作的,我们必须了解一些Javascript代码是如何从源代码转换并最终执行的

(一般来说,这取决于您使用的JS运行时(例如V8或WebKit的JavaScriptCore)。我不是这方面的专家,因此这是一个关于您通常期望的工作方式的高级概述。)

该过程的第一步涉及解析源代码的语法,并将其转换为抽象语法树,该树由代码中的标记或单个标识符组成。这些是代码中低级交互的“构建块”

具体来看第一个示例(省略括号),我们有:

!myFunction();
源代码中有四个令牌:
myFunction
()
。我们可以通过自上而下读取运算符优先级图来确定这些标记的组合顺序。(根据图表,
不是操作员)

“函数调用”具有最高优先级,因此我们可以将表达式写成

!(myFunction());
因为“函数调用”操作符(
()
)将“绑定”到
前面的
myFunction
标识符操作员

同样,对于第二个示例(同样,省略括号):

我们有代币
myObject
myProperty
。向下阅读图表,我们看到“成员访问”(
)的优先级(18)高于“逻辑非”(15),因此此表达式相当于

!(myObject.myProperty);
如果这两个运算符的优先顺序颠倒,我们将使用

(!myObject).myProperty;
为了解决您关于约定的问题:最终,我们只需编写
!myObject.myProperty,(正如大多数JS程序员所做的那样),因为我们直观地期望属性访问具有比逻辑否定更高的优先级


什么时候加入括号在很大程度上取决于你的品味,你需要对括号的合理性做出良好的判断。如果我们有100%或0%的时间可以选择使用括号,那么我们的代码将无法阅读。在这两者之间有一条中间道路,最好的方法是阅读大量JS代码,并对社区的惯例有一种直观的感觉。当你刚开始的时候,犯更多的错误是不会有伤害的;一旦你掌握了专业知识,你可能会喜欢一种更简洁的编码风格。

。只有在
中,方括号才有意义!(firstFn()&&secondFn())
这种情况下,需要两个或两个以上的运算符。只要测试一下,如果它以某种方式工作一次,它将始终以同样的方式工作(至少就帕伦斯而言)@dandavis,这是一个非常糟糕的建议。@dandavis,你知道,因为你在学校学了多年代数。有一个给定的规则集,运算符优先级,应该在标准资源中查找,而不是由用户猜测。点是运算符。括号也是运算符。@Kay谢谢!我更新了我的答案。就我的知识而言,我在这里的基础有些不稳固(不是ECMAScript解析规则方面的专家);理想情况下,有人可以编辑我的答案以确保其正确性。
(!myObject).myProperty;