四妖胀、操作符
4.1 一元操作符
4.1.1 遞增和遞減操作符
一元操作符即遞增(++
)和遞減(--
)(而各自有兩個版本:前置型和后置型),借鑒自C
語言档礁。所有的四個操作符對任何值都適用角钩,即適用于整數(shù)、字符串呻澜、布爾值递礼、浮點數(shù)值和對象。在應(yīng)用于不同的值時羹幸,遞增和遞減操作符遵循下列規(guī)則:
- 在引用于一個包含有效數(shù)字字符和字符串時脊髓,先將其轉(zhuǎn)換為數(shù)字值,在執(zhí)行加減一的操作栅受。字符串變量變成數(shù)值變量将硝。
- 在應(yīng)用于一個不包含有效數(shù)字字符的字符串時,將變量的值設(shè)置為
NaN
屏镊,字符串變量變成數(shù)值變量依疼。 - 在應(yīng)用于布爾值
false
(true
)時,先將其轉(zhuǎn)換為0
(1
)在執(zhí)行加減一操作而芥。布爾值變成數(shù)值變量律罢。 - 在應(yīng)用于浮點數(shù)值時,執(zhí)行加減一的操作
- 在應(yīng)用于對象時棍丐,先調(diào)用對象的
valueOf()
方法以取得一個可供操作的值误辑。然后對該值應(yīng)用前述規(guī)則沧踏。如果結(jié)果是NaN
,則在調(diào)用toString()
方法后再應(yīng)用前述規(guī)則巾钉。對象變量變成數(shù)值變量翘狱。
4.1.2 一元加和減操作符
加減操作符在對非數(shù)值應(yīng)用時,該操作符會像Number()
函數(shù)一樣對這個值執(zhí)行轉(zhuǎn)換睛琳。一元減操作符主要用于表示負(fù)數(shù)盒蟆,如將1
轉(zhuǎn)換成-1
。
var num = 25;
num = -num;//-25
4.2 位操作符
在
ECMAScript
中师骗,所有數(shù)值都以IEEE-754 64
位格式存儲,但位操作符并不直接操作64
位值讨惩,而是先將64
位的值轉(zhuǎn)換成32
位的整數(shù)辟癌,然后執(zhí)行操作,最后再將結(jié)果轉(zhuǎn)換回64
位荐捻。對于有符號的整數(shù)黍少,32
位中的前31
位用于表示整數(shù)的值。第32
位用于表示數(shù)值的符號:0
表示整數(shù)处面,1
表示負(fù)數(shù)厂置。JavaScript
內(nèi)部,所有數(shù)字都是以64
位浮點數(shù)形式儲存魂角,即使整數(shù)也是如此昵济。所以,1
與1.0
是相同的野揪,是同一個數(shù)访忿。某些運算只有整數(shù)才能完成,此時JavaScript
會自動把64
位浮點數(shù)斯稳,轉(zhuǎn)成32
位整數(shù)海铆。在處理有符號整數(shù)時,是不能訪問31
位的挣惰。對于無符號整數(shù)來說卧斟,第32
位不再表示符號,因為無符號只能是正數(shù)憎茂。在
ECMAScript
中珍语,當(dāng)對數(shù)值應(yīng)用位操作符時,后臺會發(fā)生如下轉(zhuǎn)換過程:64
位的數(shù)值被轉(zhuǎn)換成32
位數(shù)值唇辨,然后執(zhí)行位操作廊酣,最后再將32
位的結(jié)果轉(zhuǎn)換回64
為數(shù)值。在轉(zhuǎn)換過程會導(dǎo)致一個嚴(yán)重的副效應(yīng)赏枚,即在對特殊的NaN
和Infinity
值應(yīng)用位操作時亡驰,這兩個值會被當(dāng)成零來處理晓猛。
4.2.1 按位非(NOT:~)
var num1 = 25;//000000000000000000000000011001
var num2 = ~num1;//11111111111111111111111111100110
alert(num2);//-26
4.2.2 按位與(AND:&)
var result = 25 & 3;
alert(result);//1
000000000000000000000000011001
000000000000000000000000000011 AND
000000000000000000000000000001
4.2.3 按位或(OR:|)
var result = 25 | 3;
alert(result);//27
4.2.4 按位異或(XOR:^)
var result = 25 ^ 3;
alert(result);//26
4.2.5 左移(<<)
var oldValue = 2;//10
var newValue = oldValue << 5;//1000000,即64
注意:向左移動凡辱,多出來的位使用零填充戒职。左移不會影響操作數(shù)的符號位。
4.2.6 有符號的右移(>>)
var oldValue = 64;
var newValue = oldValue >> 5;//10透乾,即2
注意:這里也是不影響符號位的洪燥,多出來的位使用符號位填充。
4.2.7 無符號右移(>>>)
對于整數(shù)來說乳乌,無符號右移的結(jié)果與有符號右移相同捧韵,但是對負(fù)數(shù)來說,情況就不一樣了汉操,無符號右移是以零來填充位再来。而且,無符號右移操作符會把負(fù)數(shù)的二進(jìn)制碼當(dāng)成整數(shù)的二進(jìn)制碼磷瘤,由于負(fù)數(shù)以其絕對值的二進(jìn)制補碼形式表示芒篷,因此就會導(dǎo)致無符號右移后的結(jié)果非常之大。
var oldValue = -64;//111111111111111111111111111000000
var newValue = oldValue >>> 5;//134217726
4.3 布爾操作符
4.3.1 邏輯非(!)
這個操作符可以應(yīng)用于任何值采缚,無論這個值是什么數(shù)據(jù)類型针炉,這個操作符都會返回一個布爾值。邏輯非操作符首先會將某個值轉(zhuǎn)換為一個布爾值扳抽,然后再對其求反篡帕,遵循下列規(guī)則:
- 如果操作數(shù)是一個對象,返回
false
- 如果操作數(shù)是一個空字符串摔蓝,返回
true
- 如果操作數(shù)是一個非空字符串對象赂苗,返回
false
- 如果操作數(shù)是一個數(shù)值
0
,返回true
- 如果操作數(shù)是一個任意非
0
數(shù)值(包括Infinity
)贮尉,返回false
- 如果操作數(shù)是一個
null
拌滋,返回true
- 如果操作數(shù)是一個
NaN
,返回true
- 如果操作數(shù)是一個
undefined
猜谚,返回true
邏輯非操作符也可以用于將一個值轉(zhuǎn)換為與其對應(yīng)的布爾值败砂,即對操作數(shù)同時使用兩個邏輯非,此時會模擬Boolean()
轉(zhuǎn)換函數(shù)的行為魏铅。
4.3.2 邏輯與(&&)
邏輯與的真值表如下:
第一個操作數(shù) | 第二個操作數(shù) | 結(jié)果 |
---|---|---|
true |
true |
true |
true |
false |
false |
false |
true |
false |
false |
false |
false |
邏輯與操作符可以應(yīng)用于任何類型的操作數(shù)昌犹,而不僅僅是布爾值。在有一個操作數(shù)不是布爾值的情況下览芳,邏輯與操作符不一定返回布爾值斜姥,遵循下列規(guī)則:
- 如果第一個操作數(shù)是對象,則返回第二個操作數(shù)
- 如果第二個操作數(shù)是對象,則只有在第一個操作數(shù)的求值結(jié)果為
true
的情況下才會返回該對象 - 如果兩個操作數(shù)都是對象铸敏,則返回第二個操作數(shù)
- 如果第一個操作數(shù)是
null
缚忧,則返回null
- 如果第一個操作數(shù)是
NaN
,則返回NaN
- 如果第一個操作數(shù)是
undefined
杈笔,則返回undefined
邏輯與操作屬于短路操作闪水,即如果第一個操作數(shù)能夠決定結(jié)果,那么就不會再對第二個操作數(shù)求值蒙具。
4.3.3 邏輯或(||)
邏輯與的真值表如下:
第一個操作數(shù) | 第二個操作數(shù) | 結(jié)果 |
---|---|---|
true |
true |
true |
true |
false |
true |
false |
true |
true |
false |
false |
false |
邏輯或操作符可以應(yīng)用于任何類型的操作數(shù)球榆,而不僅僅是布爾值。在有一個操作數(shù)不是布爾值的情況下禁筏,邏輯或操作符不一定返回布爾值持钉,遵循下列規(guī)則:
- 如果第一個操作數(shù)是對象,則返回第一個操作數(shù)
- 如果第一個操作數(shù)的求值結(jié)果為
false
篱昔,則返回第二個操作數(shù) - 如果兩個操作數(shù)都是對象右钾,則返回第一個操作數(shù)
- 如果兩個操作數(shù)是
null
,則返回null
- 如果兩個操作數(shù)是
NaN
旱爆,則返回NaN
- 如果兩個操作數(shù)是
undefined
,則返回undefined
邏輯或操作屬于短路操作窘茁,即如果第一個操作數(shù)能夠決定結(jié)果(即為true
)怀伦,那么就不會再對第二個操作數(shù)求值。
4.4 乘性操作符
如果參與計算的某個操作數(shù)不是數(shù)值山林,后臺會先使用Number()
將其轉(zhuǎn)換為數(shù)值房待。空字符串被當(dāng)作0
驼抹,布爾值true
(false
)被當(dāng)作1
(0
)
4.4.1 乘法
在處理特殊值的情況下桑孩,乘法操作符遵循下列特殊的規(guī)則:
- 如果操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的乘法操作框冀。如果乘機(jī)超過了
ECMAScript
數(shù)值表示范圍流椒,則返回Infinity
或-Infinity
。 - 如果有一個操作數(shù)是
NaN
明也,則結(jié)果是NaN
- 如果是
Infinity
與0
相乘宣虾,則結(jié)果是NaN
- 如果是
Infinity
與非零數(shù)相乘,則結(jié)果是Infinity
或-Infinity
- 如果兩個
Infinity
相乘温数,則結(jié)果是Infinity
- 如果有一個操作數(shù)不是數(shù)值绣硝,則后臺調(diào)用
Number()
將其轉(zhuǎn)換為數(shù)值,然后再應(yīng)用上述規(guī)則撑刺。
4.4.2 除法
在處理特殊值的情況下鹉胖,除法操作符遵循下列特殊的規(guī)則:
- 如果操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的除法操作。如果商超過了
ECMAScript
數(shù)值表示范圍甫菠,則返回Infinity
或-Infinity
挠铲。 - 如果有一個操作數(shù)是
NaN
,則結(jié)果是NaN
- 如果是兩個
0
相除淑蔚,則結(jié)果是NaN
- 如果兩個
Infinity
相除市殷,則結(jié)果是NaN
- 如果是非零的有限數(shù)被零除,則結(jié)果是
Infinity
或-Infinity
刹衫。 - 如果是
Infinity
被任何非零數(shù)值除醋寝,則結(jié)果是Infinity
或-Infinity
。 - 如果有一個操作數(shù)不是數(shù)值带迟,則后臺調(diào)用
Number()
將其轉(zhuǎn)換為數(shù)值音羞,然后再應(yīng)用上述規(guī)則。
4.4.3 求模
在處理特殊值的情況下仓犬,求模操作符遵循下列特殊的規(guī)則:
- 如果操作時都是數(shù)值瀑粥,執(zhí)行常規(guī)的求模脑奠,返回余數(shù)
- 如果被除數(shù)是無窮大值而除數(shù)是有限大的數(shù)值,則結(jié)果是
NaN
- 如果被除數(shù)是有限大的數(shù)值而除數(shù)是零,則結(jié)果是
NaN
- 如果是兩個
Infinity
相除樊销,則結(jié)果是NaN
- 如果被除數(shù)是有限大而除數(shù)是無窮大的數(shù)值,則結(jié)果是被除數(shù)
- 如果被除數(shù)是零檩坚,則結(jié)果是零
- 如果有一個操作數(shù)不是數(shù)值氧苍,則后臺調(diào)用
Number()
將其轉(zhuǎn)換為數(shù)值,然后再應(yīng)用上述規(guī)則点骑。