一、ECMAScript 一元運算符
一元運算符只有一個參數,即要操作的對象或值。它們是 ECMAScript 中最簡單的運算符。
1、delete
delete 運算符刪除對以前定義的對象屬性或方法的引用。
var o = new Object;
o.name = "David";
alert(o.name); //輸出 "David"
delete o.name;
alert(o.name); //輸出 "undefined"
delete 運算符不能刪除開發者未定義的屬性和方法。例如,下面的代碼將引發錯誤:
delete o.toString;
因為 toString() 方法是原始的 ECMAScript 方法,不是開發者定義的。
2、void
void 運算符對任何值返回 undefined。
提示:請記住,沒有返回值的函數真正返回的都是 undefined。
3、前增量(++num)/前減量(--num)運算符
直接從 C(和 Java)借用的兩個運算符是前增量運算符和前減量運算符。
所謂前增量運算符,就是數值上加 1,形式是在變量前放兩個加號(++):
++iNum; //等價于 iNum = iNum + 1;
--iNum; //等價于 iNum = iNum - 1;
- 注意增量和減量運算符都發生在計算表達式之前。先自增(減)再計算
- 兩者優先級相同,按照從左到右的計算。
4、后增量/后減量運算符
還有兩個直接從 C(和 Java)借用的運算符,即后增量運算符和后減量運算符。
后增量運算符也是給數值上加 1,形式是在變量后放兩個加號(++):
iNum++; //等價于 iNum = iNum + 1;
iNum--; //等價于 iNum = iNum - 1;
區別:與前綴式運算符不同的是,后綴式運算符是在計算過包含它們的表達式后才進行增量或減量運算的。先計算再自增(減)。
兩者優先級相同。
5、一元加法和一元減法
一元加法本質上對數字無任何影響:
var iNum = 20;
iNum = +iNum;
alert(iNum); //輸出 "20"
注意:盡管一元加法對數字無作用,但對字符串卻有有趣的效果,會把字符串轉換成數字。
var sNum = "20";
alert(typeof sNum); //輸出 "string"
var iNum = +sNum;
alert(typeof iNum); //輸出 "number"
當一元加法運算符對字符串進行操作時,它計算字符串的方式與 parseInt()
相似,主要的不同是只有對以 "0x" 開頭的字符串(表示十六進制數字),一元運算符才能把它轉換成十進制的值。因此,用一元加法轉換 "010",得到的總是 10,而 "0xB" 將被轉換成 11。
一元減法就是對數值求負(例如把 20 轉換成 -20)
與一元加法運算符相似,一元減法運算符也會把字符串轉換成近似的數字,此外還會對該值求負。
var sNum = "20";
alert(typeof sNum); //輸出 "string"
var iNum = -sNum;
alert(iNum); //輸出 "-20"
alert(typeof iNum); //輸出 "number"
二、ECMAScript 位運算符
位運算符是在數字底層(即表示數字的 32 個數位)進行操作的。
1、重溫整數
ECMAScript 整數有兩種類型,即有符號整數(允許用正數和負數)和無符號整數(只允許用正數)。在 ECMAScript 中,所有整數字面量默認都是有符號整數,這意味著什么呢?
有符號整數使用 31 位表示整數的數值,用第 32 位表示整數的符號,0 表示正數,1 表示負數。
- 有符號整數數值范圍從 -2147483648 到 2147483647。
- 無符號整數的數值范圍為 0 到 4294967295。
可以以兩種不同的方式存儲二進制形式的有符號整數,一種用于存儲正數,一種用于存儲負數。正數是以真二進制形式存儲的,前 31 位中的每一位都表示 2 的冪,從第 1 位(位 0)開始,表示 20,第 2 位(位 1)表示 21。沒用到的位用 0 填充,即忽略不計。
負數也存儲為二進制代碼,不過采用的形式是二進制補碼。計算負數二進制補碼的步驟有三步:
- 確定該數字的非負版本(絕對值)的二進制表示(例如,要計算 -18的二進制補碼,首先要確定 18 的二進制表示)
- 求得二進制反碼,即要把 0 替換為 1,把 1 替換為 0
- 在二進制反碼上加 1
要確定 -18 的二進制表示,首先必須得到 18 的二進制表示,如下所示:
0000 0000 0000 0000 0000 0000 0001 0010
接下來,計算二進制反碼,如下所示:
1111 1111 1111 1111 1111 1111 1110 1101
最后,在二進制反碼上加 1,如下所示:
1111 1111 1111 1111 1111 1111 1110 1101
1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110
因此,-18 的二進制表示即 1111 1111 1111 1111 1111 1111 1110 1110。記住,在處理有符號整數時,開發者不能訪問 31 位。
有趣的是,把負整數轉換成二進制字符串后,ECMAScript 并不以二進制補碼的形式顯示,而是用數字絕對值的標準二進制代碼前面加負號的形式輸出。例如:
var iNum = -18;
alert(iNum.toString(2)); //輸出 "-10010"
這段代碼輸出的是 "-10010",而非二進制補碼,這是為避免訪問位 31。
另一方面,無符號整數把最后一位作為另一個數位處理。在這種模式中,第 32 位不表示數字的符號,而是值 231。由于這個額外的位,無符號整數的數值范圍為 0 到 4294967295。對于小于 2147483647 的整數來說,無符號整數看來與有符號整數一樣,而大于 2147483647 的整數則要使用位 31(在有符號整數中,這一位總是 0)。
把無符號整數轉換成字符串后,只返回它們的有效位。
注意:所有整數字面量都默認存儲為有符號整數。只有 ECMAScript 的位運算符才能創建無符號整數。
2、位運算 NOT
位運算 NOT 由否定號(~)表示,它是 ECMAScript 中為數不多的與二進制算術有關的運算符之一。
位運算 NOT 是三步的處理過程:
- 把運算數轉換成 32 位數字
- 把二進制數轉換成它的二進制反碼
- 把二進制數轉換成浮點數
位運算 NOT 實質上是對數字求負,然后減 1。
var iNum1 = 25; //25 等于 00000000000000000000000000011001
var iNum2 = ~iNum1; //轉換為 11111111111111111111111111100110
alert(iNum2); //輸出 "-26"
3、位運算 AND
位運算 AND 由和號(&)表示,直接對數字的二進制形式進行運算。它把每個數字中的數位對齊,然后用下面的規則對同一位置上的兩個數位進行 AND 運算:同真為真,一假為假。
例如,要對數字 25 和 3 進行 AND 運算,代碼如下所示:
var iResult = 25 & 3;
alert(iResult); //輸出 "1"
25 和 3 進行 AND 運算的結果是 1。為什么?分析如下:
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
AND = 0000 0000 0000 0000 0000 0000 0000 0001
4、位運算 OR
位運算 OR 由符號(|)表示,也是直接對數字的二進制形式進行運算。在計算每位時,OR 運算符采用下列規則:一真為真,同假為假。
5、位運算 XOR
位運算 XOR 由符號(^)表示,當然,也是直接對二進制形式進行運算。XOR 不同于 OR,當只有一個數位存放的是 1 時,它才返回 1。
對 25 和 3 進行 XOR 運算,代碼如下:
var iResult = 25 ^ 3;
alert(iResult); //輸出 "26"
25 和 3 進行 XOR 運算的結果是 26:
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
XOR = 0000 0000 0000 0000 0000 0000 0001 1010
可以看出,在兩個數字中,共有 4 個數位存放的是 1,這些數位被傳遞給結果。二進制代碼 11010 等于 26
6、左移運算<<
左移運算由兩個小于號表示(<<)。它把數字中的所有數位向左移動指定的數量。例如,把數字 2(等于二進制中的 10)左移 5 位,結果為 64(等于二進制中的 1000000):
var iOld = 2; //等于二進制 10
var iNew = iOld << 5; //等于二進制 1000000 十進制 64
注意:在左移數位時,數字右邊多出 5 個空位。左移運算用 0 填充這些空位,使結果成為完整的 32 位數字。
注意:左移運算保留數字的符號位。
7、有符號右移運算
有符號右移運算符由兩個大于號表示(>>)。它把 32 位數字中的所有數位整體右移,同時保留該數的符號(正號或負號)。有符號右移運算符恰好與左移運算相反
8、無符號右移運算
無符號右移運算符由三個大于號(>>>)表示,它將無符號 32 位數的所有數位整體右移。對于正數,無符號右移運算的結果與有符號右移運算一樣。
用有符號右移運算中的例子,把 64 右移 5 位,將變為 2:
var iOld = 64; //等于二進制 1000000
var iNew = iOld >>> 5; //等于二進制 10 十進制 2
對于負數,情況就不同了。
無符號右移運算用 0 填充所有空位。對于正數,這與有符號右移運算的操作一樣,而負數則被作為正數來處理。
由于無符號右移運算的結果是一個 32 位的正數,所以負數的無符號右移運算得到的總是一個非常大的數字。例如,如果把 -64 右移 5 位,將得到 134217726。
三、ECMAScript Boolean 運算符
Boolean 運算符有三種:NOT、AND 和 OR。
-
ToBoolean 操作
在學習各種邏輯運算符之前,讓我們先了解一下 ECMAScript-262 v5 規范中描述的 ToBoolean 操作。
抽象操作 ToBoolean 將其參數按照下表中的規則轉換為邏輯值:
ToBoolean 操作
1、邏輯 NOT 運算符
在 ECMAScript 中,邏輯 NOT 運算符與 C 和 Java 中的邏輯 NOT 運算符相同,都由感嘆號(!)表示。
與邏輯 OR 和邏輯 AND 運算符不同的是,邏輯 NOT 運算符返回的一定是 Boolean 值。
邏輯 NOT 運算符的行為如下:
- 如果運算數是對象,返回 false
- 如果運算數是數字 0,返回 true
- 如果運算數是 0 以外的任何數字,返回 false
- 如果運算數是 null,返回 true
- 如果運算數是 NaN,返回 true
- 如果運算數是 undefined,發生錯誤
判斷 ECMAScript 變量的 Boolean 值時,也可以使用邏輯 NOT 運算符。這樣做需要在一行代碼中使用兩個 NOT 運算符。無論運算數是什么類型,第一個 NOT 運算符返回 Boolean 值。第二個 NOT 將對該 Boolean 值求負,從而給出變量真正的 Boolean 值。
var bFalse = false;
var sRed = "red";
var iZero = 0;
var iThreeFourFive = 345;
var oObject = new Object;
document.write("bFalse 的邏輯值是 " + (!!bFalse));
document.write("sRed 的邏輯值是 " + (!!sRed));
document.write("iZero 的邏輯值是 " + (!!iZero));
document.write("iThreeFourFive 的邏輯值是 " + (!!iThreeFourFive));
document.write("oObject 的邏輯值是 " + (!!oObject));
結果:
bFalse 的邏輯值是 false
sRed 的邏輯值是 true
iZero 的邏輯值是 false
iThreeFourFive 的邏輯值是 true
oObject 的邏輯值是 true
2、邏輯 AND 運算符
在 ECMAScript 中,邏輯 AND 運算符用雙和號(&&)表示:
邏輯 AND 運算的運算數可以是任何類型的,不止是 Boolean 值。
如果某個運算數不是原始的 Boolean 型值,邏輯 AND 運算并不一定返回 Boolean 值:
- 如果一個運算數是對象,另一個是 Boolean 值,返回該對象。
- 如果兩個運算數都是對象,返回第二個對象。
- 如果某個運算數是 null,返回 null。
- 如果某個運算數是 NaN,返回 NaN。
- 如果某個運算數是 undefined,發生錯誤。
與 Java 中的邏輯 AND 運算相似,ECMAScript 中的邏輯 AND 運算也是簡便運算,即如果第一個運算數決定了結果,就不再計算第二個運算數。對于邏輯 AND 運算來說,如果第一個運算數是 false,那么無論第二個運算數的值是什么,結果都不可能等于 true。
3、邏輯 OR 運算符
ECMAScript 中的邏輯 OR 運算符與 Java 中的相同,都由雙豎線(||)表示:
與邏輯 AND 運算符相似,如果某個運算數不是 Boolean 值,邏輯 OR 運算并不一定返回 Boolean 值:
- 如果一個運算數是對象,并且該對象左邊的運算數值均為 false,則返回該對象。
- 如果兩個運算數都是對象,返回第一個對象。
- 如果最后一個運算數是 null,并且其他運算數值均為 false,則返回 null。
- 如果最后一個運算數是 NaN,并且其他運算數值均為 false,則返回 NaN。
- 如果某個運算數是 undefined,發生錯誤。
與邏輯 AND 運算符一樣,邏輯 OR 運算也是簡便運算。對于邏輯 OR 運算符來說,如果第一個運算數值為 true,就不再計算第二個運算數。
四、ECMAScript 乘性運算符
ECMAScript 的乘性運算符與 Java、C、Perl 等于語言中的同類運算符的運算方式相似。需要注意的是,乘性運算符還具有一些自動轉換功能。
1、乘法運算符
乘法運算符由星號(*)表示,用于兩數相乘。
不過,在處理特殊值時,ECMAScript 中的乘法還有一些特殊行為:
-如果結果太大或太小,那么生成的結果是 Infinity 或 -Infinity。
- 如果某個運算數是 NaN,結果為 NaN。
- Infinity 乘以 0,結果為 NaN。
- Infinity 乘以 0 以外的任何數字,結果為 Infinity 或 -Infinity。
- Infinity 乘以 Infinity,結果為 Infinity。
注釋:如果運算數是數字,那么執行常規的乘法運算,即兩個正數或兩個負數為正數,兩個運算數符號不同,結果為負數。
2、除法運算符
除法運算符由斜杠(/)表示,用第二個運算數除第一個運算數。
與乘法運算符相似,在處理特殊值時,除法運算符也有一些特殊行為:
- 如果結果太大或太小,那么生成的結果是 Infinity 或 -Infinity。
- 如果某個運算數是 NaN,結果為 NaN。
- Infinity 被 Infinity 除,結果為 NaN。
- Infinity 被任何數字除,結果為 Infinity。
- 0 除一個任何非無窮大的數字,結果為 NaN。
- Infinity 被 0 以外的任何數字除,結果為 Infinity 或 -Infinity。
3、取模運算符
除法(余數)運算符由百分號(%)表示,使用方法如下:
var iResult = 26%5; //等于 1
與其他乘性運算符相似,對于特殊值,取模運算符也有特殊的行為:
- 如果被除數是 Infinity,或除數是 0,結果為 NaN。
- Infinity 被 Infinity 除,結果為 NaN。
- 如果除數是無窮大的數,結果為被除數。
- 如果被除數為 0,結果為 0。
注釋:如果運算數是數字,那么執行常規的算術除法運算,返回除法運算得到的余數。
五、ECMAScript 加性運算符
1、加法運算符
與乘性運算符一樣,在處理特殊值時,ECMAScript 中的加法也有一些特殊行為:
- 某個運算數是 NaN,那么結果為 NaN。
- -Infinity 加 -Infinity,結果為 -Infinity。
- Infinity 加 -Infinity,結果為 NaN。
- +0 加 +0,結果為 +0。
- -0 加 +0,結果為 +0。
- -0 加 -0,結果為 -0。
不過,如果某個運算數是字符串,那么采用下列規則:
如果兩個運算數都是字符串,把第二個字符串連接到第一個上。
如果只有一個運算數是字符串,把另一個運算數轉換成字符串,結果是兩個字符串連接成的字符串。
2、減法運算符
與加法運算符一樣,在處理特殊值時,減法運算符也有一些特殊行為:
- 某個運算數是 NaN,那么結果為 NaN。
- Infinity 減 Infinity,結果為 NaN。
- -Infinity 減 -Infinity,結果為 NaN。
- Infinity 減 -Infinity,結果為 Infinity。
- -Infinity 減 Infinity,結果為 -Infinity。
- +0 減 +0,結果為 +0。
- -0 減 -0,結果為 -0。
- +0 減 -0,結果為 +0。
- 某個運算符不是數字,那么結果為 NaN。
六、ECMAScript 關系運算符
關系運算符執行的是比較運算。每個關系運算符都返回一個布爾值。
1、常規比較方式
關系運算符小于、大于、小于等于和大于等于執行的是兩個數的比較運算,比較方式與算術比較運算相同。最后都返回一個布爾值。
對于字符串,第一個字符串中每個字符的代碼都與會第二個字符串中對應位置的字符的代碼進行數值比較。完成這種比較操作后,返回一個 Boolean 值。問題在于大寫字母的代碼都小于小寫字母的代碼,這意味這著可能會遇到下列情況:
var bResult = "Blue" < "alpha";
alert(bResult); //輸出 true
在上面的例子中,字符串 "Blue" 小于 "alpha",因為字母 B 的字符代碼是 66,字母 a 的字符代碼是 97。要強制性得到按照真正的字母順序比較的結果,必須把兩個數轉換成相同的大小寫形式(全大寫或全小寫的),然后再進行比較:
var bResult = "Blue".toLowerCase() < "alpha".toLowerCase();
alert(bResult); //輸出 false
2、比較數字和字符串
另一種棘手的狀況發生在比較兩個字符串形式的數字時,比如:
var bResult = "25" < "3";
alert(bResult); //輸出 "true"
上面這段代碼比較的是字符串 "25" 和 "3"。兩個運算數都是字符串,所以比較的是它們的字符代碼("2" 的字符代碼是 50,"3" 的字符代碼是 51)。
不過,如果把某個運算數該為數字,那么結果就有趣了:
var bResult = "25" < 3;
alert(bResult); //輸出 "false"
這里,字符串 "25" 將被轉換成數字 25,然后與數字 3 進行比較,結果不出所料。
無論何時比較一個數字和一個字符串,ECMAScript 都會把字符串轉換成數字,然后按照數字順序比較它們。
不過,如果字符串不能轉換成數字又該如何呢?考慮下面的例子:
var bResult = "a" < 3;
alert(bResult);
你能預料到這段代碼輸出什么嗎?字母 "a" 不能轉換成有意義的數字。不過,如果對它調用 parseInt() 方法,返回的是 NaN。根據規則,任何包含 NaN 的關系運算符都要返回 false,因此這段代碼也輸出 false:
var bResult = "a" >= 3;
alert(bResult); //false
通常,如果小于運算的兩個值返回 false,那么大于等于運算必須返回 true,不過如果某個數字是 NaN,情況則非如此。
七、ECMAScript 等性運算符
ECMAScript 提供了兩套等性運算符:等號和非等號用于處理原始值,全等號和非全等號用于處理對象。
1、等號和非等號
在 ECMAScript 中,等號由雙等號(==)表示,當且僅當兩個運算數相等時,它返回 true。非等號由感嘆號加等號(!=)表示,當且僅當兩個運算數不相等時,它返回 true。為確定兩個運算數是否相等,這兩個運算符都會進行類型轉換。
執行類型轉換的規則如下:
- 如果一個運算數是 Boolean 值,在檢查相等性之前,把它轉換成數字值。false 轉換成 0,true 為 1。
- 如果一個運算數是字符串,另一個是數字,在檢查相等性之前,要嘗試把字符串轉換成數字。
- 如果一個運算數是對象,另一個是字符串,在檢查相等性之前,要嘗試把對象轉換成字符串。
- 如果一個運算數是對象,另一個是數字,在檢查相等性之前,要嘗試把對象轉換成數字。
在比較時,該運算符還遵守下列規則:
- 值 null 和 undefined 相等。
- 在檢查相等性時,不能把 null 和 undefined 轉換成其他值。
- 如果某個運算數是 NaN,等號將返回 false,非等號將返回 true。
- 如果兩個運算數都是對象,那么比較的是它們的引用值。如果兩個運算數指向同一對象,那么等號返回 true,否則兩個運算數不等。
重要提示:即使兩個數都是 NaN,等號仍然返回 false,因為根據規則,NaN 不等于 NaN。
下表列出了一些特殊情況,以及它們的結果:2、全等號和非全等號
全等號由三個等號表示(===),只有在無需類型轉換運算數就相等的情況下,才返回 true。全等必須值和類型都相等才返回true。
八、ECMAScript 條件運算符
variable = boolean_expression ? true_value : false_value;
如果 Boolean_expression 為 true,就把 true_value 賦給變量;如果它是 false,就把 false_value 賦給變量。
九、ECMAScript 賦值運算符
賦值運算符:
- 簡單的賦值運算符由等號(=)實現,只是把等號右邊的值賦予等號左邊的變量。
- 復合賦值運算是由乘性運算符、加性運算符或位移運算符加等號(=)實現的
每種主要的算術運算以及其他幾個運算都有復合賦值運算符:
- 乘法/賦值(*=)
- 除法/賦值(/=)
- 取模/賦值(%=)
- 加法/賦值(+=)
- 減法/賦值(-=)
- 左移/賦值(<<=)
- 有符號右移/賦值(>>=)
- 無符號右移/賦值(>>>=)
十、ECMAScript 逗號運算符
用逗號運算符可以在一條語句中執行多個運算。
例如:
var iNum1 = 1, iNum = 2, iNum3 = 3;
逗號運算符常用變量聲明中。
本文摘自W3shcool教程