写js时间长了,运算符优先级很可能自然而然的就形成习惯了,也不需要特别注意优先级的问题。
至少到目前为止,我也没有真正了解过js当中所有运算符的具体优先级。也没有出过什么重大的问题。
但是直到今天,在eslint的提示下,发现了一个因为优先级导致的重大问题。
我们经常会做一些函数封装的事情,那么很自然的,在函数体内,一开始的地方,得需要做一些常规的参数类型的判断。
如果我们需要对数组进行一些操作之后,再返回一个新的数组,那么在封装函数时,必然是需要把数组作为参数传递到函数内部的,那么在函数体开始时,判断参数是否为数组类型,就显得尤为重要。
function func (arr) { if (arr instanceof Array) { // 逻辑操作 } }
这种判断很正常,但是如果我们需要做大量的逻辑操作,而在参数是非数组的情况下,直接抛出错误呢?
function func (arr) { if (!arr instanceof Array) throw new Error('该方法仅仅适用于数组') // 逻辑操作 }
是不是很多人都这么写的?
然后测试一下,不管传入数组还是非数组,都能得到我们想要的判断,是不是很happy?判断完成了。
那么这种写法真的对吗?
在vue-cli项目当中,默认打开eslint,如果你这么写了,你回发现eslint就会一直提示你,这里有问题。
这究竟在提示啥呢?仔细看一下他的提示语:其实意思是说,意外否定了'instanceof'运算符的左操作数。而不是对instanceof操作结果取非。
那很明白了,就是!操作符的优先级要高于instanceof,是不是呢?看文档吧!运算符优先级。
打开文档之后,在汇总表查看:
按照优先级,逻辑非为16,instanceof为11。那结果很明了了,逻辑非的优先级高于instanceof。无论如何都得验证一下,是吧!
既然我们想通过 !arr instanceof Array的值为false,判断他为非数组,那么!![] instanceof Array的值是不是就是true了呢?
很抱歉,结果并非我们所期望的。那么如何解决这个问题?也很简单,就是加圆括号。
毕竟在js所有运算符当中,圆括号的优先级最高!