ECMA-262用於操作數據值的操作符包括: 算術操作符 位操作符 關係操作符 相等操作符 ECMAScript操作符的不同之處在於:它能夠適用於很多值,包括字元串,數字值,布爾值,甚至是對象。(在應用於對象時,相應的操作符通常會調用對象的valueOf()和(或)toString()方法,以便取得 ...
ECMA-262用於操作數據值的操作符包括:
算術操作符
位操作符
關係操作符
相等操作符
ECMAScript操作符的不同之處在於:它能夠適用於很多值,包括字元串,數字值,布爾值,甚至是對象。(在應用於對象時,相應的操作符通常會調用對象的valueOf()和(或)toString()方法,以便取得可以操作的值。)
1.一元操作符
(1)遞增和遞減操作符
需要註意的是:
eg:
前置++age:變數的值在語句被求值之前改變。
後置age++:變數的值在語句被求值之後改變。
執行前置遞增和遞減操作時,變數的值都是在語句被求值以前改變的(在電腦科學領域中,這種情況通常被稱作復效應。)
遞增和遞減操作符應用於其他數據類型遵循的規則詳見高程書P37。
(2)一元加和減操作符
當一元加和減操作符放在數值前面時,相當於正負號。
當一元加和減操作符放在非數值類型的數據類型前時,它會依照相應的規則進行數據類型的轉換。
2.位操作符
ECMAScript中所有的數值都是以IEEE-754 64位格式存儲的,但是為操作符並不是直接操作64位的值。而是先將64位的值轉換成32位的整數,然後執行操作,最後在將結果轉換回64位。但是這個轉換過程也導致了一個嚴重的復效應,即在對特殊的NaN和Infinity值應用位操作時,這兩個值都會被當成0來處理。
如果對非數值應用位操作符,會先使用Number()函數將該值轉換為一個數值(自動完成),再進行位操作,最終得到一個數值。
(1)負數以二進位補碼的格式存儲。
計算一個數值二進位補碼的過程如下:
1.求這個數值絕對值的二進位碼。
2.求二進位的反碼。
3.得到的二進位反碼加1。
(2)ECMAScript中,當我們以二進位字元串形式輸出一個負數時,我們看到的這個負數的絕對值的二進位碼前面加了一個負號,它以更合乎邏輯的形式展示了出來。
eg:
1 var num=-18; 2 alert(num.toString(2));
註:
預設情況下,ECMAScript中的所有整數都是有符號整數。當然,也存在無符號整數,無符號整數的值更大,因為第32位不再表示符號,可以用來表示數值。
(3)按位非(NOT):符號~
按位非的本質是操作數的負值減1。
(4)按位與(AND):符號&
(5)按位或(OR):符號|
(6)按位異或(XOR):符號^
(7)左移:符號<<,左移操作出現的空位以0填充。左移不會影響數值的符號位。
(8)有符號的右移:符號>>,右移時保留符號位,右移出現的空位由符號位填充。
(9)無符號的右移:符號>>>,無符號的右移產生的空位以0填充。所以,正數的無符號右移和有符號右移結果一樣,負數就不一樣了。其次,無符號右移操作符會把負數的二進位碼當成正數的二進位碼,而且,由於負數以其絕對值的二進位的補碼表示,因此就會導致無符號右移後的結果非常之大。
3.布爾操作符
布爾操作符有三個:非(NOT:!),與(AND:&&),或(OR:||)
(1)邏輯非:運用該操作符時,首先會對它的操作數轉換成一個布爾值,然後對其求反。詳細規則見高程P44。
註:同時使用兩個邏輯非操作符,可以得到這個值真正對應的布爾值,與使用Boolean()函數的結果相同。
eg:alert(!!123);//true
alert(!!NaN);//false
(2)邏輯與:該操作可以應用於任何類型的操作數,在有一個操作數不是布爾值的時候,邏輯與操作就不一定返回布爾值。詳細規則見高程P45。
註:邏輯與操作屬於短路操作,即如果第一個操作數能夠決定結果,那麼就不會再對第二個操作數求值。
eg:
1 var found=true; 2 var result=(found && someUndefinedVariable); //這裡發生錯誤 3 alert(result); //這一行不會執行
上面代碼出現錯誤的原因是,因為found的值是true,所有邏輯與會繼續對第二個變數求值,但是由於第二個變數沒有定義,所以導致錯誤。說明不能再邏輯與中使用未定義的值。
將found的值改為false,由於邏輯與的短路特性,就不會出現錯誤。如下所示:
1 var found=false; 2 var result=(found && someUndefinedVariable);//不會發生錯誤 3 alert(result);//會執行
(3)邏輯或:與邏輯與相似,也是短路操作符,詳細的規則見高程P46。
註:
可以利用邏輯或的倆避免為變數賦null或undefined值。
eg: var myobject = preferredObject || backupObject;
ECMAScript程式的賦值語句經常會使用到這種模式,如果 preferredObject不是null,那麼它的值將會賦給myobject,如果是null,則將backupObject的值賦給myobject。
4.乘性操作符:乘法(*),除法(/),求模(%)
當操作數是非數值的時候,後臺會先使用Number()轉型函數將其轉換為數值。
(1)乘法。詳細的規則見高程P47。
(2)除法。詳細的規則見高程P47。
(3)求模。詳細的規則見高程P48。
5.加性操作符:加法(+),減法(-)。
(1)加法
有以下兩種情況:
一. 當兩個操作數都是數值時,執行常規的加法運算,詳細的規則見高程P48。
二. 如果兩個操作數存在字元串,當兩個操作數都是字元串時,直接將兩個字元串拼接起來,如果只有一個操作數是字元串,則將另一個操作數轉換為字元串,然後在將兩個字元串拼接起來。
註意:
如果有一個操作數是對象,數值或是布爾值,則調用toString()方法取得相應的字元串值,然後在應用前面的關於字元串的規則。對於undefined和null,則調用String()函數並取得字元串“undefined”和“null”。
一個因為忽視加法操作符數據類型而導致的常見的錯誤:
eg:
1 var num1=2; 2 var num2=8; 3 var text="The sum of 2 and 8 is:"+ num1 +num2; 4 alert(text);
結果如下:
要得到正確的結果,可以像下麵這樣使用圓括弧:
1 var num1=2; 2 var num2=8; 3 var text="The sum of 2 and 8 is:"+ (num1 +num2); 4 alert(text);
結果如下:
(2)減法。詳細的規則見高程P49。
6.關係操作符: < , > , <= , >= ,這幾個操作都返回布爾值。詳細的規則見高程P50。
需要註意的是:當兩個操作數都是字元串是,則比較兩個字元串對應的字元編碼值。
eg:
1 var result="23"<"3"; 2 alert(result);
結果:
出現這樣結果的原因是:兩個操作數都是字元串,,所以比較的是字元編碼,(“2”的字元編碼是50,而“3”的字元編碼是51。)
可以將其中一個操作數改為數值,這樣的比較時,後臺會自動將另一個操作數也轉換為數值類型,這樣就可以得到正確的結果,如下所示:
1 var result="23"<3; 2 alert(result);
7.相等操作符
(1)相等和不相等(== or !=):先轉換再比較。(強制轉型)詳細的規則見高程P51。
註:
null和undefined是相等的,且在比較相等性之前不能將null和undefined轉換為其它任何值。
如果兩個操作數書對象,則比較它們是否是同一對象。
(2)全等和不全等(=== or !===):僅比較而不轉換。詳細的規則見高程P52。
eg:
1 var result1=("55"==55); 2 var result2=("55"===55); 3 alert(result1); 4 alert(result2);
結果依次如下:
1 var result1=(null==undefined); 2 var result2=(null===undefined); 3 alert(result1); 4 alert(result2);
結果依次如下:
8.條件操作符
eg:
1 var max=(5>10)?5:10; 2 alert(max);
9.賦值操作符(=):把右側的值賦給左側的變數。複合賦值操作符詳見高程P53。
註:複合賦值操作符可以簡化賦值操作,但是它們不會帶來任何性能上的提升。
10.逗號操作符
(1)聲明多個變數
eg:var num1=1,num2=4,num3=9;
(2)賦值,逗號操作符總是會返回表達中的最後一項。
eg:var num=(4,5,6,0);
alert(num);
結果: