javascript篇-----操作符
ECMA-262描述了一組用於操作數據值的操作符,包括算數操作符 、位操作符、關系操作符和相等操作符。ECMAScript操作符的與眾不同之處在於,它們能夠適用於很多值,例如字符串、數字值、布爾值、甚至對象。不過,在應用於對象時,相應的操作符通常都會調用對象的valueOf()和toString()方法,以便取得可以操作的值。
一元操作符
顧名思義,一元操作符就是只能操作一個值的操作符,它包括遞增和遞減操作符、一元加和減操作符四種,下面會都會討論到。
遞增和遞減操作符
遞增和遞減操作符都各有兩個版本:前置型和後置型。從字面上理解,前置型就是操作符位於要操作的變量之前,而後置型則位於要操作的變量之後。
1 { 2 var age = 29; 3 // 前置型 4 ++ age 5 -- age 6 // 後置型 7 age ++ 8 age -- 9 }
雖說前置遞增(遞減)和後置遞增(遞減)在一般情況的使用上,它們得到運算結果是一致的,都可以理解為以下代碼的等價
1 { 2 var age = 29; 3 age = age + 1; 4 // 在運算結果上等價於age++和++age 5 var index = 7; 6 age = age - 1; 7 // 在運算結果上等價於age--和--age 8 }
但是,它們兩者的實際的運算過程上是存在很大區別的。前置遞增(遞減)操作會在包含它們的語句被求值之前執行,而後置遞增(遞減)操作則會在包含它們的語句被求值之後執行。下面的代碼展示了這個過程的區別。
1 { 2 // 後置遞增 3 var num1 = 2; 4 var num2 = 20; 5 var num3 = num1++ + num2; // 結果為22,過程為 num3[22] = num1[2] + num2[20]; num1[3] = num1[2] + 1; 6 var num4 = num1 + num2; // 結果為23,過程為 num4[23] = num[3] + num2[20]; 7 // 前置遞增 8 var num5 = 2; 9 var num6 = 20; 10 var num7 = ++num5 + num6; // 結果為26,過程為 num5[3] = num5[2] + 1; num7[23] = num5[3] + num6[20];11 var num8 = num5 + num6; // 結果為23,過程為 num8[23] = num5[3] + num6[20]; 12 }
遞增和遞減操作符不僅適用於整數,還可以用於字符串、布爾值、浮點數值和對象。在應用於不同的值時,遞增和遞減操作符遵循下列規則。
- 在應用於一個包含有效數字字符的字符串時,先將其轉換為數字值,再執行加減1的操作。字符串變量變成數值變量。
- 在應用於一個不包含有效數字字符的字符串時,將變量的值設置為NaN。字符串變量變成數值變量。
- 在應用於布爾值false時,先將其轉換為0再執行加減1的操作。布爾值變量變成數值變量。
- 在應用於布爾值true時,先將其轉換為1再執行加減1的操作。布爾值變量變成數值變量。
- 在應用於浮點數值時,執行加減1的操作。
- 在應用於對象時,先調用對象的valueOf()方法以取得一個可供操作的值。然後對該值應用前述規則。如果結果時NaN,則在調用toString()方法後在應用前述規則。對象變量變成數值變量。
1 { 2 var s1 = ‘1‘; 3 var s2 = ‘z‘; 4 var b = true; 5 var f = 1.2; 6 var o = { 7 valueOf: function () { 8 return 3; 9 } 10 }; 11 12 s1++;// 變成數值2 13 s2++;// 變成數值NaN 14 b--;// 變成數值0 15 f++;// 變成浮點數2.2 16 o--;// 變成數值2 17 }
一元加和減操作符
一元加減操作符和我們在數學學的是完全一樣的。一元加操作符放在數值前面,對數值是不會有任何影響的。但放在非數值前面時,操作符會像Number()轉型函數一樣對這個非數值執行轉換。(Number轉換函數的講述可以參照http://www.cnblogs.com/xhni0/p/7461138.html)。與一元加操作符相似,都一元見操作符主要用於表示符號,在將一元減操作符應用於數值時,該值會變成負數。而當應用於非數值時,一元減操作符遵循與一元加操作符相同的規則,最後再將得到的數值轉換為數值。
位操作符
有了解過計算機組成原理的應該都不會不熟悉位操作符。位操作符用於在最基本的層次上,即按內存中表示數值的位來操作數值。ECMAScript中的所有數值都以IEEE-754 64位格式存儲,但是位操作符並不直接操作64位的值。而是先將64位的值轉換為32位的整數,然後執行操作,最後再將結果轉換回64位。對於開發人員來說,由於64位存儲格式是透明的,因此整個過程就像只存在32位的整數一樣。
對於有符號的整數,32位中的前31為用於表示整數的值。第32位用於表示數值的符號:0表示整數,1表示負數。這個表示符號的位叫做符號位。符號位的值決定了其他位數值的格式。
正數以純二進制格式存儲,31位中的每一位都表示2的冪。第一位表示20,第二位表示21,以此類推。
負數同樣以二進制碼存儲,但使用的格式是二進制補碼。二進制補碼通過下列步驟獲得,
- 求這個數值絕對值的二進制碼;
- 求二進制碼的反碼;
- 得到的二進制碼加1;
值得註意的事,對特殊的NaN和Infinity值應用位操作時,這兩個值都會被當做0來處理。
按位非
按位非操作符由一個波浪線(~)表示,執行按位非的結果就是返回數值的反碼,在操作的本質上就是:操作數的負數減1.
按位與
按位與操作符有一個和號字符(&)表示,它有兩個操作數。在本質上講,按位與操作就是將兩個數值的每一位對齊,然後根據下表中的規則,對相同位置上的兩個數執行AND操作。
第一個數值的位 | 第二個數值的位 | 結果 |
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
按位與操作只在兩個數值的對應位都是1時才返回1,任何一位是0,結果都是0。
按位或
按位或操作符由一個豎線符號(|)表示,同樣也有兩個操作數。但遵循是如下的規則。
第一個數值的位 | 第二個數值的位 | 結果 |
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
按位或操作在有一個位是1的情況下就返回1,而只有在兩個位都是0的情況下才返回0。
按位異或
按位異或操作符由一個插入符號(^)表示,也有兩個操作符。真值表如下。
第一個數值的位 | 第二個數值的位 | 結果 |
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
按位異或與按位或的不同之處在於,這個操作在兩個數值對應位只有一個1時才返回1,如果對應位的兩位都是1或都是0,則返回0。
左移
左移操作符有兩個小於號(<<)表示,這個操作符會將數值的所有位向左移動指定的位數。移位後的右側空位用0來填充它們。左移操作不會影響操作數的符號位。
有符號右移
有符號的右移操作符由兩個大於號(>>)表示,這個操作符會將數值向右移動,但保留符號位,移位後的左側空位用0來填充它們。有符號的右移操作符也不會影響操作數的符號位。
無符號右移
無符號右移操作符由3個大於號(>>>)表示,這個操作符會將數值的所有32位都向右移動,對於正數來說,無符號右移的結果與有符號右移相同。
布爾操作符
布爾操作符一共有3個:非、與和或。
邏輯非
邏輯非操作符由一個嘆號(!)表示,可以應用於任何的值,操作的結果都會返回一個布爾值。邏輯非操作首先會將它的操作數轉換為一個布爾值,然後對其進行求反。具體規則如下,
- 如果操作數是一個對象,返回false;
- 如果操作數是一個空字符串,返回true;
- 如果操作數是一個非空字符串,返回false;
- 如果操作數是數值0,返回true;
- 如果操作數是任何非0數值(包括Infinity),返回false;
- 如果操作數是null,返回true;
- 如果操作數是NaN,返回true;
- 如果操作數是undefined,返回true;
1 { 2 console.log(!false);// true 3 console.log(!‘blue‘);// false 4 console.log(!0);// true 5 console.log(!NaN);// true 6 console.log(!‘‘);// true 7 console.log(!12345)// false 8 }
邏輯非操作符也可以用於將一個值轉換為與其對應的布爾值。而同時使用兩個邏輯非操作符,實際上就會模擬Boolean()轉型函數的行為。實際上,第一個邏輯非操作會基於無論什麽操作數返回一個布爾值,而第二個邏輯非操作則對該布爾值求反,最終就得到了一個值的所對應的布爾值。
1 { 2 console.log(!!‘blue‘);// true 3 console.log(!!0);// false 4 console.log(!!NaN);// false 5 console.log(!!‘‘);// false 6 console.log(!!12345)// true 7 }
邏輯與
邏輯與操作符由兩個和號(&&)表示,有兩個操作數。真值表如下,
第一個操作數 | 第二個操作數 | 結果 |
true | true | true |
true | false | false |
false | true | false |
false | false | false |
邏輯與操作可以應用於任何類型的操作數,而不僅僅是布爾值。在有一個操作數不是布爾值的情況下,邏輯與操作就不一定返回布爾值。而是遵循如下規則,
- 如果第一個操作數是對象,則返回第二個操作數;
- 如果第二個操作數是對象,則只有在第一個操作數的求值為true的情況下才能返回該對象;
- 如果兩個操作數都是對象,則返回第二個操作數;
- 如果有一個操作數是null,則返回null;
- 如果有一個操作數是NaN,則返回NaN;
- 如果有一個操作數是undefined,則返回undefined。
邏輯與操作屬於短路操作,如果第一個操作數能夠決定結果,那麽就不會在對第二個求值。因為對於邏輯與操作而言,如果第一個操作數是false,那麽無論第二個操作數是什麽值,結果都不在可能是true了。這個特性在寫代碼時常常用於在變量有定義的情況下執行接下來的運算。
1 { 2 // 邏輯與的短路操作 3 var boolTrue = true; 4 var name1 = ‘name1‘; 5 console.log(boolTrue && name1)// name1 6 var boolFalse = false; 7 var name2 = ‘name2‘; 8 console.log(boolFalse && name2)// false 9 // 邏輯與的短路操作的用法 10 var num1; 11 console.log(num1 && num1 + 3)// undefined,語句num+3因為num1的值為undeifned而不執行 12 num1 = 2; 13 console.log(num1 && num1 + 3)// 5 14 }
邏輯或
邏輯或操作符由兩個豎線(||)符號表示,有兩個操作符,真值表如下
第一個操作數 | 第二個操作數 | 結果 |
true | true | true |
true | false | true |
false | true | true |
false | false | false |
和邏輯與操作相似,如果有一個操作數不是布爾值,邏輯或也不一定返回布爾值,而是遵循如下規則,
- 如果第一個操作數是對象,則返回第一個操作數;
- 如果第一個操作數的求值結果為false,則返回第二個操作數;
- 如果兩個操作數都是對象,則返回第一個操作數;
- 如果兩個操作數都是null,則返回null;
- 如果兩個操作數都是NaN,則返回NaN;
- 如果兩個操作數都是undefined,則返回undefined;
與邏輯與操作符相似,邏輯或操作符也是短路操作符。如果第一個操作數的求值結果為true,就不會對第二個操作數求值了。它的這個特征在代碼時則常常用於函數變量的初始化賦值。
1 { 2 // 邏輯或的短路操作 3 var boolTrue = true; 4 var name1 = ‘name1‘; 5 console.log(boolTrue && name1)// true 6 var boolFalse = false; 7 var name2 = ‘name2‘; 8 console.log(boolFalse && name2)// name2 9 // 邏輯或的短路操作的用法 10 function test (num1, num2) { 11 console.log(num1 || num1 = 2); 12 console.log(num2 || num2 = 2); 13 } 14 test(1)//傳入num1變量都是不傳入num2變量 15 // 輸出的結果為 1 2 16 // num1有傳入值,不執行num1 = 2的賦值語句 17 // num2無傳入值,執行num2 = 2的賦值語句 18 }
乘性操作符
乘性操作符有3個,乘法、除法和求模,這些操作符在操作數為非數值的情況下都會執行自動的類型轉換。
乘法
乘法操作符由一個星號(*)表示,用於計算兩個數值的乘積。而在處理非數值時,乘法操作符遵循下列的規則。
- 如果操作數都是數值,執行常規的乘法計算,即兩個整數或者兩個負數相乘的結果還是正數,而如果只有一個操作數有符號,那麽結果就是負數。如果乘積超過了ECMAScript數值的表示範圍,則返回Infinity或-Infinity;
- 如果有一個操作數是NaN,則結果是NaN;
- 如果是Infinity和0相乘,則結果是NaN;
- 如果是Infinity與非0數值相乘,則結果是Infinity或-Infinity,取決於有符號操作數的符號;
- 如果是Infinity和Infinity相乘,則結果是Infinity;
- 如果有一個操作數不是數值,則在後臺調用Number()將其轉換為數值,然後再應用上面的規則;
除法
除法操作符有一個斜線符號(/)表示,執行第二個操作數除第一個操作數的計算。和乘法操作符相似,除法操作符對非數值也會進行特殊的處理,規則如下。
- 如果操作數都是數值,執行常規的除法計算。兩個正數或兩個負數相處的結果還是正數,而如果只有一個操作數有符號,那麽結果就是負數。如果商超過了ECMAScript數值的表示範圍,則返回Infinity或-Infinity;
- 如果有一個操作數是NaN,則結果是NaN;
- 如果是Infinity被Infinity除,則結果是NaN;
- 如果是零被零除,則結果是NaN;
- 如果是非零的有限數被零除,則結果是Infinity或-Infinity,取決於有符號操作數的符號;
- 如果是Infinity被任何非零數值除,則結果是Infinity或-Infinity,取決於有符號操作數的符號;
- 如果有一個操作數不是數值,則會調用Number()轉換函數將其轉換為數值,然後再應用上面的規則。
求模
求模(余數)操作符由一個百分號(%)表示,運算規則如下。
- 如果操作數都是數值,執行常規的除法計算,返回除得的余數;
- 如果被除數是無窮大值而除數是有限大的數值,則返回是NaN;
- 如果被除數是有限大的數值而除數是零,則結果是NaN;
- 如果是Infinity被Infinity除,則結果是NaN;
- 如果被除數是有點大的數值而除數是無窮大的數值,則結果是被除數;
- 如果被除數是零,則結果是零;
- 如果有一個操作數不是數值,則在後臺調用Number()將其轉換為數值,然後再應用上面的規則。
加性操作符
加性操作符包括加法和減法操作符兩種。和乘性操作符相似,在運用於非數值時,加性操作符也會在後臺進行特殊的數據類型轉換。
加法
加法操作符(+)的規則如下。
- 如果兩個操作數都是數值,執行常規的加法計算,然後根據下列規則返回結果,
- 如果有一個操作數是NaN,則結果是NaN;
- 如果是Infinity和Infinity,則結果是Infinity;
- 如果是-Infinity和-Infinity,則結果是-Infinity;
- 如果是Infinity和-Infinity, 則結果是NaN;
- 如果是+0加+0,則結果是+0;
- 如果是-0加-0,則結果是-0;
- 如果是+0加-0,則結果是-0;
- 如果有一個操作數是字符串,則根據下列規則運算,
- 如果兩個操作數都是字符串,則將第二個操作數與第一個操作數拼接起來;
- 如果只有一個操作數是字符串,則將另一個操作數轉換為字符串,然後再將兩個字符串拼接起來。
- 如果有一個操作數是對象、數值或布爾值,則調用它們的toString()方法取得相應的字符串值,然後再應用字符串的計算規則;
1 { 2 var num = 1 + 1;// 2 3 var str = 1 + ‘1‘;// ‘11‘ 4 }
減法
減法操作符(-)的規則,
- 如果是兩個操作數都是數值,則執行常規的算術減法操作並返回結果;
- 如果有一個操作數是NaN,則結果是NaN;
- 如果是Infinity減Infinity,則結果是NaN;
- 如果是-Infinity減-Infinity,則結果是NaN;
- 如果是Infinity減-Infinity,則結果是Infinity;
- 如果是-Infinity減Infinity,則結果是-Infinity;
- 如果是+0減+0,則結果是+0;
- 如果+0減-0,則結果是-0;
- 如果是-0減-0,則結果是+0;
- 如果有一個操作數是字符串、布爾值、null或undefined,則先調用Number()函數將其轉換為數值,然後再根據前面的規則執行減法運算。如果轉換的結果是NaN,則減法的結果就是NaN;
- 如果有一個操作數是對象,則調用對象的valueOf()方法以取得表示該對象的數值。如果得到的值是NaN,則調用的結果就是NaN。如果對象沒有valueOf()方法,則調用其toString()方法並將得到的字符串轉換為數值;
1 { 2 var num1 = 5 - true;// 4,true轉換為1 3 var num2 = NaN - 1;// NaN 4 var num3 = 5 - 3;// 2 5 var num4 = 5 - ‘‘;// 5,空字符串‘‘被轉換為0 6 var num5 = 5 - ‘2‘;// 3,‘2‘轉換為2 7 var num6 = 5 - null;// 5,null轉換為0 8 }
關系操作符
關系操作符用於對兩個值進行比較,返回一個布爾值true或false。比較的規則如下。
- 如果兩個操作數都是數值,則執行數值比較;
- 如果兩個操作數都是字符串,則比較兩個字符串對象的字符串編碼值;
- 如果一個操作數是數值,則將另一個操作數轉換為一個數值,然後執行數值比較;
- 如果一個操作數是對象,則調用這個對象的valueOf()方法,用得到的結果按照前面的規則執行比較。如果對象沒有valueOf()方法,則調用toString()方法,並用得到的結果根據前面的規則執行比較。
- 如果一個操作數是布爾值。則先將其轉換為數值,然後再執行比較;
相等操作符
ECMAScript的相等操作符分兩組,相等和不相等-----先轉換在比較,全等和不全等-----僅比較而不轉換。
相等和不相等
相等操作符由兩個等於號(==)表示,如果兩個操作數相等,則返回true。而不相等操作符由嘆號後跟等於號(!=)表示,如果兩個操作數不相等,則返回true。這兩個操作符都會先執行強制轉換,然後再比較它們的相等性。
在轉換不同的數據類型時,相等和不相等操作符遵循如下規則。
- 如果有一個操作數是布爾值,則在比較相等性之前先將其轉換為數值-----false轉換為0,而true轉換為1;
- 如果一個操作數是字符串,另一個操作數是數值,則在比較相等性之前先將字符串轉換為數值;
- 如果一個操作數是對象,另一個操作數不是,則調用對象的valueOf()方法,用得到的基本數據類型值按照前面的規則進行比較;
這兩個操作符在進行比較時同時還要遵循下面的規則,
- null和undefined是相等的;
- 要比較相等性之前,不能將null和undefined轉換成其他任何值;
- 如果有一個操作數是NaN,則相等操作符返回false,而不相等操作符返回true。;即使兩個操作數都是NaN,相等操作符也返回false。因為NaN不等於NaN的規則存在。
- 如果兩個操作數都是對象,則比較他們是不是同一個對象。如果兩個操作數都指向同一個對象,則相等操作符返回true,否則返回false;
1 { 2 null == undefined;// true 3 ‘NaN‘ == NaN;// false 4 5 == NaN;// false 5 NaN == NaN;// false 6 NaN != NaN;// true 7 false == 0;// true 8 true == 1;// true 9 true == 2;// false 10 undefined == 0;// false 11 null == 0;// false 12 ‘5‘ == 5;// true 13 }
全等和不全等
除了在比較之前不轉換操作數之外,全等和不全等操作符沒什麽區別。全等操作符有3個等於號(===)表示,只有在兩個操作數未經轉換的相等的情況下返回true。而不全等操作符有一個嘆號和兩個等於號(!==)表示,它在兩個操作數未經轉換就相等的情況下返回true。
條件操作符
條件操作符遵循如下語法形式,
variable = boolean expression ? true_value : false_value;
這行代碼的還以就是基於對boolean expression求值的結果,決定給變量variable賦什麽值。如果求值結果為true,則給變量variable賦tru_value值;如果求值結果為false,則給變量variable賦false_value值。
1 { 2 var num1 = 1; 3 var num2 = 2; 4 var num3 = 5; 5 var num4 = num1 > num2 ? (num3 + num1) : (num3 + num2);//7 6 }
賦值操作符
賦值操作符由等於號(=)表示,作用是把右側的值賦給左側的變量。而如果在等號前面在添加上乘性操作符、加性操作符或為操作符,就可以完成復合賦值操作。每一個主要算數操作符都有對象的復合賦值操作符,如下
- 乘/賦值(*=);
- 除/賦值(/=);
- 模/賦值(%=);
- 加/賦值(+=);
- 減/賦值(-=);
- 左移/賦值(<<=);
- 有符號右移/賦值(>>=);
- 無符號右移/賦值(>>>=);
逗號操作符
逗號操作符用於一條語句執行多個操作的情況。
1 { 2 var num = 2, name = ‘li‘, bool = true; 3 }
javascript篇-----操作符