4.5 加性操作符
4.5.1 加法
如果兩個操作符都是數值,執行常規的加法計算,然后根據下列規則返回結果:
- 如果有一個操作數是
NaN
,則結果是NaN
- 如果是
Infinity
加Infinity
,則結果是Infinity
- 如果是
-Infinity
加-Infinity
,則結果是-Infinity
- 如果是
Infinity
加-Infinity
,則結果是NaN
- 如果是
+0
加+0
,則結果是+0
- 如果是
-0
加-0
,則結果是-0
- 如果是
+0
加-0
,則結果是+0
不過,如果有一個操作數是字符串,那么就要應用如下規則:
- 如果兩個操作數都是字符串,則將第二個操作數與第一個操作數拼接起來
- 如果只有一個操作數是字符串,則將另一個操作數轉換為字符串,然后再將兩個字符串拼接起來。
4.5.2 減法
如果兩個操作符都是數值,執行常規的減法計算,然后根據下列規則返回結果:
- 如果有一個操作數是
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()
方法并將得到的字符串轉換為數值。
4.6 關系操作符
當關系操作符的操作數使用了非數值時,也要及你想那個數據轉換或完成某些奇怪的操作。以下就是相應的規則。
- 如果兩個操作數都是數值,則執行數值比較
- 如果兩個操作數都是字符串,則比較兩個字符串對應的字符編碼值
- 如果另一個操作數是數值,則將另一個操作數轉換為一個數值,然后執行數值比較
- 如果一個操作數是對象,則調用這個對象的
valueOf()
方法,用得到的結果按照前面的規則執行比較。如果對象沒有valueOf()
方法,則調用toString()
方法,并用得到的結果根據前面的規則執行比較 - 如果一個操作數是布爾值,則先將其轉換為數值,然后再執行比較。
4.7 相等操作符
在ECMAScript
中,提供兩組操作符:相等和不想等——先轉換再比較;全等和不全等——僅比較而不轉換
4.7.1 相等和不想等
相等操作符由兩個等于號(==
)表示,如果兩個操作數相等,則返回true
。而不想等操作符由!=
表示,如果兩個操作數不想等,則返回true
。這兩個操作符都會先轉換操作數(通常為強制轉型),然后再比較它們的相等性。
在轉換不同的數據類型時,相等和不想等操作符遵循下列基本規則:
- 如果有一個操作數是布爾值,則在比較相等性之前先將其轉換為數值——
false
轉換為0
,而true
轉換為1
- 如果一個操作數是字符串,另一個操作數是數值,在比較相等性之前先將字符串轉換為數值
- 如果一個操作數是對象,另一個操作數不是,則調用對象的
valueOf()
方法,用得到的基本類型值按照前面的規則進行比較
這兩個操作符在進行比較時則要遵循下列規則:
表達式 | 值 | 表達式 | 值 |
---|---|---|---|
null == undefined |
true |
true == 1 |
true |
"NaN"== NaN |
false |
true == 2 |
false |
5 == NaN |
false |
undefined == 0 |
false |
NaN == NaN |
false |
null == 0 |
false |
NaN != NaN |
true |
"5" == 5 |
true |
false == 0 |
true |
4.7.2 全等和不全等
除了在比較之前不轉換操作數之外,全等和不全等操作符與相等和不想等操作符沒有什么不同。全等操作符由===
表示,它只在兩個操作數未經轉換就相等的情況下返回true
。不全等操作符由!==
表示,它只在兩個操作數未經轉換就不相等的情況下返回true
。
記?。?/strong>null == undefined
會返回true
,因為它們是類似的值;但null === undefined
會返回false
,因為它們是不同類型的值。
五、語句
5.1 for-in語句
for-in
語句是一種精準的迭代語句,可以用來枚舉對象的屬性。以下是for-in
語句的語法:
for(var propName in window){
document.write(propName);
}
說明:結果和常規的for
循環沒有什么不同,只是語法更簡潔。但是,如果表示要迭代的對象的變量值為null
或undefined
,for-in
語句會拋出錯誤。建議在使用此語法之前檢查對象的值是不是null
或undefined
。
5.2 label語句
直接看示例:
start : for(var i = 0; i < count; i++){
alert(i);
}
這個例子中定義的start
標簽可以在將來由break
或continue
語句引用。加標簽的語句一般都是要與for
語句等循環語句配合使用。
5.3 break和continue語句
具體的語法這里不細說,和C
語言一樣。下面看一個示例:
var num = 0;
outermost:
for(var i = 0; i < 10; i++){
for(var j = 0; j < 10; j++){
if(i == 5 && j == 5){
continue outermost;
}
num++;
}
}
alert(num);//95
說明:當i、j
的值都是5
的時候,則跳出循環。
5.4 with語句(不建議使用)
with
語句的作用是將代碼的作用域設置到一個特定的對象中??匆粋€示例:
var qs = location.search.substring(1);
var hostName = location.hostName;
var url = location.href;
可以看到上述代碼都包含location
對象,如果使用with
語句,可以將上述代碼改寫如下:
with(location){
var qs = search.substring(1);
var hostName = hostName;
var url = href;
}
六、函數
相關細節這里不多數。嚴格模式對函數有一些限制:
- 不能把函數命名為
eval
或arguments
; - 不能把參數命名為
eval
或arguments
; - 不能出現兩個命名參數同名的情況
如果發生上述情況,代碼將無法執行。
6.1 理解參數
在ECMAScript
中,函數不介意傳遞進來多少各參數,也不在乎傳遞進來參數是什么數據類型。也就是說,即便你定義的函數只接受兩個參數,在調用這個函數時也未必一定要傳遞兩個參數。實際上,傳遞進來的參數全部保存在arguments
對象中,此對象與數組類似(并不是Array
的實例),但是可以像數組那樣訪問每一個元素。關于arguments
的行為,還有一點比較有意思,就是它的值永遠與對應命名參數的值保持同步。如:
function doAdd(num1, num2){
arguments[1] = 10;
alert(arguments[0] + num2);
}
每次執行這個doAdd()
函數都會重寫第二個參數,將第二個參數的值修改為10
。因為arguments
對象中的值會自動反映到對應的命名參數,所以修改arguments[1]
,也就修改了num2
,結果它們都變為10
。注意:沒有傳遞值的命名參數將自動被賦予undefined
值。所有的參數傳遞都是值,不可能通過引用傳遞參數。
6.2 沒有重載
function addSomeNumber(num){
return num + 10;
}
//會覆蓋掉上一個同名函數
function addSomeNumber(num){
return num + 200;
}
var result = addSomeNumber(100);//300
說明:從代碼中可以看到無法像其他面向對象語言那樣進行重載,當然,可以通過檢查傳入函數中參數的類型和數量并做出不同的反應來模仿方法的重載。