当前位置: 首页 > Web前端 > JavaScript

关于运算符优先级的一些陷阱

时间:2023-03-26 21:06:41 JavaScript

前言JS中的表达式非常强大,对应着各种与表达式相关的操作符。这些运算符可以任意组合,赋予了JS极大的灵活性和强大的组合能力。在很多情况下,可以使用运算符代替很多功能只能用几行语句来实现。强大的运营商背后,隐藏着优先级带来的隐患。大多数JS开发人员对运算符的优先级不是很熟悉。可能会因为优先级的关系导致很多问题,甚至会造成实际的生产事故。因此,在拥抱运营商带来的强大动力的同时,运营商带来的潜在危险也不容忽视。Example一个例子,我们之前可能有以下旧代码//Order是一个用于创建订单的构造函数){//somecodeCode}业务变了,现在我们需要在订单不是Order的实例时做一些事情。对于新手,可能会这样写if(orderinstanceofOrder){}else{//Somecode}这样可以正常工作,但是条件为真的块是空的,很不优雅,所以熟悉的人with操作符可以写成if(!orderinstanceofOrder){//somecode}Traps这段代码的执行可以参考下面的测试用例letorder=newOrder();//我们的代码!orderinstanceofOrder//false//我们期望执行的优先级!(orderinstanceofOrder)//false目前,它看起来是正确的但是如果是下面的用例letorder={};//我们的代码!orderinstanceofOrder//false//我们想要的执行优先级!(orderinstanceofOrder)//true这会产生不同的结果,尚未包含在括号运算符中,这可能会导致问题,因为!比instanceof具有更高的优先级,所以上面的表达式实际上是这样工作的(!order)instanceofOrder;此表达式始终返回false并且我们期望inorder不是Order实例返回true,否则false因此,对于上述情况,必须手动加上括号,才能保证优先级!(订单实例);上面的情况是一个常见的例子,我们经常使用!xxx,!xx()!xx.xx[xx](),所以另外两个可能出现上面问题的例子Operators!typeof和===参考下面代码//表达式1typeofa==="string"//和表达式2!typeofa==="string"例程用法,我们知道typeof的优先级大于of===所以我们知道第一个表达式是这样执行的(typeofa)==="string"其实!typeof的优先级与typeof相同,但大于===的优先级所以上面的表达式2实际上是这样的(!(typeofa))==="string"而我们预期的执行是这样的!((typeofa)==="string")对于上述情况,建议使用!==运算符代替,这样就不需要使用!在前面,不需要考虑优先级的问题。如果确实出现类似情况,则需要添加!在前面,并确保添加括号逻辑运算符&&||??对于这三个,如果不熟悉,可能会认为优先级是一样的,这可能会导致下面的代码a&&b&&c||d因为&&的优先级比||高,所以上面的代码实际上先执行的级别是,(a&&b&&c)||d这样可能不符合预期,有时候我们的预期是这样的a&&b&&(c||d)这种情况下,必须加上括号来保证Priority为??运算符,我们可以把它看成是和||一样的类型,当左边不满足条件的时候就用右边的。其实这三者的优先级是&&高于||和??,||和??是相同的优先级参考mdnwebdocs运算符优先级结论我建议大多数时候不同运算符组合使用时,加上括号。如果一眼看不出优先级,最好加上括号来判断优先级