JavaScript浅析 -- 运算符和优先级

2018-07-09  本文已影响0人  Da_xiong

一、运算符

JavaScript中的运算符,主要用于连接简单表达式,组成一个复杂的表达式。在运算过程中,会根据需要将操作数转换成特定的类型进行运算,最后输出指定的类型。我个人习惯将他分为6大类进行记忆:算术运算符,比较运算符,布尔运算符,赋值运算符,位运算符,其他运算符。

(一)算术运算符(10个)

说明:
(1) x++先参与运算然后x再做加一操作。如console.log(2 - a++)相当于console.log(2-a); a = a+1;++x先进行加一操作再参与运算。如console.log(2 - ++a)相当于a=a+1;console.log(2-a)
(2) 取余的正负号取决于第一位数,如-7%2为-1;7%-2为1,所以为了得到负数的正确余值需要用绝对函数,如判断num是否为偶数时Math.abs(num) % 2
(3) +x一般用来做转数的操作,如+new Date()、+[] // 0、+{} // NaN、+true // 1,其实相当于Number(x)只是结果为正。
(4) +号运算时才确定是相加还是连接,如果有一方是字符串则变成连接符。对于对象相加先调用valueOf()再调用toString(),但是valueOf()返回的一般是原对象,所以一般都会调用toString()。特例,Date对象反着来,先toString()再valueOf()。如'3' + 5 + 6 // 3563 + 5 + '6' // ‘86’

(二)比较运算符(8个)

说明:
===是严格等于,要求类型和数值都相等(其中NaN===NaN为false);而==会进行隐式转换之后再比较值是否相等。具体的转换规则参考文章

(三)布尔运算符(4个)

说明:
(1) !a会对a先做Boolean()转换操作,然后对转换的布尔值进行取反,如!0为!Boolean(0)结果为true。
(2) 且和或的运算均为短路运算,即a && b两个为true才为true,a为false则不再管b;a || b一个为true则为true,a为true则不再管b。
(3) condition ? a : b相当于if(condition) { a } else { b }

(四)位运算符(7个)
(五)赋值运算符(11个)
(六)其他运算符

二、运算符的优先级

运算符的优先级顺序如下(上大于下,左大于右)
++、--(右结合大于左结合)、-(转负数)、+(转数)、~(位反)、!(取反)
delete、typeof、void
*、/、%、+、-
<=、>=、==、!=、===、!==
||、&&、?:、赋值、,

说明:
(1) 优先级指的是同时出现的时候先计算高优先级部分,而不是说先当做这个。例如转数的加号优先级高于加法的加号,1+'3‘++new Date()不是说把加号先当做转数符,如果是那么1+'3'结果是4但结果是'13‘,很显然是作为加号使用。而是说先计算+new Date()得到时间戳1531139346042,再执行1+'3‘+1531139346042
(2) ++、--之类的操作数必须是可以放在赋值左边的数而不能是常数,比如4++会报错。还有下面的例子也要注意:

var a=0, b=0;
a+++b; // 0
a; // 1
b; // 0

右结合的优先级高于左结合和加号,上面会先找有没有右结合,找到a++先运算,所以运算顺序是(a++)+b
(3) typeof的优先级比加减乘除还高,所以一般习惯把操作数加上括号,如

typeof 2*3; // NaN
typeof (2*3); // 'number'
typeof 2+3; // 'number3'

(4) 逻辑非优先级高于加减乘除,但逻辑或和逻辑与比加减乘除优先级低。!2*0相当于(!2)*0
(5) 逻辑或||、逻辑与&&的短路运算要注意,且返回的是其中的一个表达式,而不是布尔值。1 && "hi" || 0的结果是'hi'
(6) 赋值的优先级非常低。

a = b == c // 相当于a = (b==c)

下面这个例子,先自己猜一下结果,再看正确答案。arr.length会报错吗?

var arr, arr2;
arr2 = arr = [1, 2, 3];
arr[arr.length] = arr = 4;
console.log(arr);
console.log(arr2);

上面这个,由于赋值的优先级非常低最后才执行,arr[arr.length] = arr = 4其实是先算的arr[arr.length]是指向arr[3]的一个地址(和arr2[3]指向的是同一个),接着4赋值给arr然后arr的值4赋值给这块地址指向的内存(也就是arr2[3]变成了4)。所以结果是arr为4,arr2为[1, 2, 3, 4]。
再来看个例子也是类似。

var a = {n: 1};
var b = a;
a.x = a = {n:2};
console.log(a.x); // undefined
console.log(b.x); // {n: 2}
上一篇下一篇

猜你喜欢

热点阅读