JS型別轉換
前言
JS是弱型別動態語言,不同型別的資料也能進行運算,那麼掌握不同資料型別進行運算時的規則就非常重要了。
邏輯運算
-
邏輯非(不進行任何運算的單一運算元可用邏輯非來倒推)
-
如果運算元是一個物件,返回
false
; -
如果運算元是一個空字串,返回
true
; -
如果運算元是一個非空字串,返回
false
; -
如果運算元是0,返回
true
; -
如果運算元是任意非0數值(包括
Infinity
),返回false
; -
如果運算元是
null
,返回true
; -
如果運算元是
NaN
,發揮true
; -
如果運算元是
undefined
,返回true
;
alert(!false);//true alert(!"blue");//false alert(!0);//true alert(!NaN);//true alert(!"");//true alert(!12345);//false
邏輯非操作符也可以用於將一個值轉換為與其對應的布林值,同時使用兩個邏輯非操作符實際上就會模擬
Boolean()
轉型函式的行為。 -
如果運算元是一個物件,返回
-
邏輯與
- 如果第一個運算元是物件,則返回第二個運算元;
-
如果第二個運算元是物件,則石油在第一個運算元的求職結果為
true
的情況下才會返回該物件; - 如果兩個運算元都是物件,則返回第二個運算元;
-
如果第一個運算元是
null
,則返回null
; -
如果第一個運算元是
NaN
,則返回NaN
; -
如果第一個運算元是
undefined
,則返回undefined
;
邏輯與的操作,只要第一個運算元能轉換為false
那麼第二個運算元不會計算。
/* error */ var a = true; var result= (a && b);//變數b沒有宣告,並且a為true,所以直譯器會繼續對b求值而導致報錯 alert(result) /* success */ var a = false; var result= (a && b);//變數雖然b沒有宣告,但是a為false,直譯器不會對b求值 alert(result)
- 邏輯或:邏輯或和邏輯與相似,只要第一個運算元求值結果為true,就不會對第二個運算元求值,型別轉換參考邏輯與。
算數運算子
-
乘法
-
如果兩個運算元都是數值,執行常規的乘法計算,如果成績超過了
ECMAScript
數值的表示範圍,返回Infinity
或-Infinity
; -
如果有一個運算元是
NaN
,則結果是NaN
; -
如果是
Infinity
與0
相乘,則結果是NaN
; -
如果是
Infinity
與非0數值相乘,則結果是Infinity
或-Infinity
,取決於有符號運算元的符號; -
如果是
Infinity
與Infinity
相乘,則結果是Infinity
; -
如果有一個擦作書不是數值,則在後臺呼叫
Number()
將其轉換為數值,然後在應用上面的規則。
-
如果兩個運算元都是數值,執行常規的乘法計算,如果成績超過了
-
除法:除法的處理方式與乘法類似,有兩點不同:
-
如果是零被零除,結果是
NaN
; -
如果是非零的優先數被零除,則結果是
Infinity
或-Infinity
,取決於有符號運算元的符號;
-
如果是零被零除,結果是
-
加法:
-
如果有一個運算元是
NaN
,則結果是NaN
; -
如果是
Infinity
加Infinity
,則結果是Infinity
; -
如果是
-Infinity
加-Infinity
,結果是-Infinity
; -
如果是
Infinity
加-Infinity
,結果是NaN
; -
如果是
+0
加+0
,結果是+0
; -
如果是
-0
加-0
,結果是-0
; -
如果是
+0
加-0
,結果是+0
; - 如果兩個運算元都是字串,則將第二個運算元與第一個運算元憑藉起來;
- 如果只有一個運算元是字串,則將另一個運算元轉換為字串,然後在將兩個字串拼接起來;
-
如果有一個運算元是物件、數值、布林值則呼叫他們的
toString()
方法取得相應的字串值,對於undefined
和null
,則呼叫String()
函式轉化為字串。
var result = 5 + 5; console.log(result);//10 var result = 5 + '5'; console.log(result);//55 var a = function () { console.log(1); } var b = 1; console.log(a + b);//function () {console.log(1);}1 var a = true; var b = 1; console.log(a + b);//2 var a = false; var b = 1; console.log(a + b);//1
-
如果有一個運算元是
-
減法:減法的處理方式和加法類似,只是字串、布林值、
null
和undefined
的處理方式不同:-
如果有一個運算元是字串、布林值、
null
或undefined
,則現在後臺呼叫Number()
函式將其轉換為數值,然後再根據上面加法類似的規則進行減法計算,如果轉換的結果是NaN
則計算結果就是NaN
; -
如果有一個運算元是物件,則呼叫物件的
valueOf()
方法來取得表示該物件的數值。如果得到的值是NaN
則劍法的結果就是NaN
。如果物件沒有valueOf()
方法,則呼叫其toString()
方法並將得到的字串轉換為數值。
var a = function () { console.log(1); } var b = 1; console.log(a - b);//NaN var a = true; var b = 1; console.log(a - b);//0 var a = false; var b = 1; console.log(a - b);//-1 var a = undefined; var b = 1; console.log(a - b);//NaN var a = null; var b = 1; console.log(a - b);//-1 var a = { name: "clloz", age: 26 } b = 1; console.log(a - b);//NaN
注意在算術運算中
null
被轉化為0
而undefined
被轉化為NaN
-
如果有一個運算元是字串、布林值、
關係操作符
-
大於、小於、小於等於和大於等於:
- 如果兩個運算元都是數值,執行數值比較;
- 如果兩個運算元都是字串,則比較兩個字串對應的字元編碼值;
- 如果一個運算元是數值,則將另一個運算元轉換為一個數值然後執行數值比較;
-
如果一個運算元是物件,則呼叫物件的
valueOf()
方法,用得到的結果按照前面的規則進行比較,如果物件沒有valueOf()
方法,則呼叫toString()
方法,再用得到的結果根據前面的規則進行比較。
javascript中使用關係操作符比較兩個字串的時候會出現一些反直覺的現象,比如'23' < '3'
會返回true
,具體的比較規則是按位比較兩個字串對應位置的字元編碼值,比如比較apple
和Book
,a
的字元編碼值為97
,B
的字元編碼值為66
,所以就是'apple'>'Book'
,如果第一位相同那麼就比較第二位以此類推。
javascript使用的unicode
字符集,所以字元編碼值就是字元在unicode
字符集中的位置,我們可以用charCodeAt()
方法檢視在UTF-16
中的位置,返回0~655355
中的數字。
-
相等操作符
==
和不相等操作符!=
:先轉換在比較- 如果有一個操作符是布林值,在比較之前將其轉換為數字;
- 如果一個運算元是字串,另一個是數值,先將字串轉換為數值再比較;
-
如果一個運算元是物件,另一個運算元不是,則呼叫物件的
valueOf()
方法,用得到的基本型別值按照前面的規則進行比較; -
null
和undefined
是相等的 -
比較相等性之前,不能將
null
或者undefined
轉換為其他值; -
只要有一個而運算元是
NaN
,相等操作符就返回false
,不等操作就返回true
; -
如果兩個運算元都是物件,則比較他們是不是同一個物件,當兩個引用指向同一個物件,則返回
true
,否則返回false
;
- 全等和不全等:比較規則和相等不相等操作符相同,只是不會進行轉換再比較。
由於相等和不相等操作符存在型別轉換問題,可能會出現一些意料之外的結果,以及為了保持資料型別的一致性,儘量使用全等和不全等操作符。
條件判斷
if語句是我們最常使用的語句,而if語句的條件判斷就是個表示式,可能是我們上面遇到的任何一種情況,對於表示式的結果ECMAScript會自動呼叫Boolean()
轉換成布林值。
總結
js的資料型別轉換非常靈活,我們不用嚴格的限制變數的資料型別,但是js有些型別轉換並不十分合理,甚至有些資料型別的轉換是非常奇怪的,所以我們在寫程式碼的過程中要注意這些點,儘量使用全等和不全等,以及掌握各種資料型別轉換的情況是非常重要的。