《你不知道的JavaScript》整理(六)——強制類型轉換

來源:互聯網
上載者:User

標籤:有道   抽象   位置   允許   strong   float   返回   拼接   解釋   

JavaScript中通常分為兩種類型轉換,“隱式強制類型轉換”(implicit coercion)和“顯式強制類型轉換”(explicit coercion)。

下面所有代碼的源碼可以在此處查看。

一、強制轉換為字串(ToString)

1)ToString

基本類型值的字串化規則為:null轉換為"null",undefined轉換為"undefined",true轉換為"true"。數位字串化則遵循通用規則,不過那些極小和極大的數字使用指數形式:

// 1.07 連續乘以七個 1000var a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;// 七個1000一共21位元字console.log(a.toString()); // "1.07e21"

對普通對象來說,除非自行定義,否則toString()(Object.prototype.toString())返回內部屬性[[Class]]的值

2)JSON

JSON.stringify(..)在對象中遇到undefined、function和symbol時會自動將其忽略,在數組中則會返回null(以保證單元位置不變)。

如果對象中定義了toJSON()方法,JSON字串化時會首先調用該方法,然後用它的傳回值來進行序列化。

JSON.stringify(undefined); // undefinedJSON.stringify(function() {}); // undefinedJSON.stringify(  [1, undefined, function() {}, 4]); // "[1,null,null,4]"JSON.stringify({    a: 2,    b: function() {}}) // "{"a":2}"

 

二、強制轉換數字(ToNumber)

1)ToNumber

1. true轉換為1false轉換為0

2. undefined轉換為NaNnull轉換為0

3. ""[]轉換為0。處理失敗時返回NaN

4. ToNumber對以0開頭的十六進位數並不按十六進位處理

2)對象

對象(包括數組)會首先被轉換為相應的基本類型值,如果返回的是非數位基本類型值,則再遵循以上規則將其強制轉換為數字。

為了將值轉換為相應的基本類型值,抽象操作ToPrimitive會首先(通過內部操作DefaultValue)檢查該值是否有valueOf()方法。

如果有並且返回基本類型值,就使用該值進行強制類型轉換。如果沒有就使用toString()的傳回值(如果存在)來進行強制類型轉換。

var a = {  valueOf: function() { //先執行valueOf    return "42";  }};var b = {  toString: function() { //再執行toString    return "42";  }};var c = [4, 2];c.toString = function() {  return this.join(""); // "42"};Number(a); // 42Number(b); // 42Number(c); // 42Number(""); // 0Number([]); // 0Number(["abc"]); // NaN

 

三、強制轉換布爾值(ToBoolean)

1)假值(falsy value)

可強制類型轉換為false。包括undefinednullfalse+0-0NaN""

undefined、null、false、+0、-0、NaN、""

2)真值

[]{}function(){}都不在假值列表中。

[]、{}和function(){}

 

四、顯式強制類型轉換

1)奇特的~運算子

~x大致等同於-(x+1)

~42;    // -(42+1) ==> -43

用~~來截除數字值的小數部分~~中的第一個~執行ToInt32並反轉字位,然後第二個~再進行一次字位反轉,即將所有字位反轉回原值,最後得到的仍然是ToInt32的結果。

//奇特的~var a = "Hello World";if (~a.indexOf("lo")) { //如果未找到就返回-1,(-1+1)=0就是false   // 找到匹配! }//~~Math.floor(-49.6); // -50~~-49.6; // -49

2)顯式解析數字字串

解析允許字串中含有非數字字元,解析按從左至右的順序,如果遇到非數字字元就停止。

轉換不允許出現非數字字元,否則會失敗並返回NaN。

var a = "42";var b = "42px";Number(a); // 42parseInt(a); // 42Number(b); // NaNparseInt(b); // 42

解析字串中的浮點數可以使用 parseFloat(..) 函數。

非字串參數會首先被強制類型轉換為字串(執行toString方法)。

parseInt(0.000008); // 0 ("0" 來自於 "0.000008")parseInt(0.0000008); // 8 ("8" 來自於 "8e-7") parseInt(false, 16); // 250 ("fa" 來自於 "false") parseInt(parseInt, 16); // 15 ("f" 來自於 "function..")parseInt("0x10"); // 16 parseInt("103", 2); // 2

 

五、隱式強制類型

1)字串和數字之間的隱式強制類型轉換

如果+其中一個運算元是字串則執行字串拼接;否則執行數字加法。

如果其中一個運算元是對象(包括數組), 則對其調用 ToPrimitive 抽象操作。

var a = "42";var b = "0";a + b; // "420" 兩個都是字串var c = 42;var d = 0;c + d; // 42 兩個都是數字var a = [1, 2];var b = [3, 4];a + b; // "1,23,4" 兩個都是對象

2)隱式強制類型轉換為布爾值

以下情況,非布爾值會被隱式強制類型轉換為布爾值,遵循ToBoolean 抽 象操作規則。

1. if (..)語句中的條件判斷運算式。

2. for ( .. ; .. ; .. )語句中的條件判斷運算式(第二個)。

3. while (..)do..while(..)迴圈中的條件判斷運算式。

4. ? :中的條件判斷運算式。

5.  邏輯運算子||(邏輯或)和&&(邏輯與)左邊的運算元(作為條件判斷運算式)。

 

六、寬鬆相等和嚴格相等

常見的誤區是“ == 檢查值是否相等, === 檢查值和類型是否相等”。聽起來蠻有道理,然而 還不夠準確。

正確的解釋是:“ == 允許在相等比較中進行強制類型轉換,而 === 不允許

1)字串和數字之間的相等比較

1.如果 Type(x) 是數字, Type(y) 是字串,則返回 x == ToNumber(y) 的結果。

2.如果 Type(x) 是字串, Type(y) 是數字,則返回 ToNumber(x) == y 的結果。

2)其他類型和布爾類型之間的相等比較

1.如果 Type(x) 是布爾類型,則返回 ToNumber(x) == y 的結果。

2.如果 Type(y) 是布爾類型,則返回 x == ToNumber(y) 的結果。

3)null 和 undefined 之間的相等比較

1.如果 x 為 null , y 為 undefined ,則結果為 true 。

2.如果 x 為 undefined , y 為 null ,則結果為 true 。

4)對象和非對象之間的相等比較

1.如果 Type(x) 是字串或數字, Type(y) 是對象,則返回 x == ToPrimitive(y) 的結果。

2.如果 Type(x) 是對象, Type(y) 是字串或數字,則返回 ToPromitive(x) == y 的結果。

var a = "abc";var b = Object(a); // 和new String( a )一樣a === b; // false //b 通過 ToPromitive 進行強制類型轉換(也稱為“拆封”,unboxed或者unwrapped) ,並返回標量基本類型值 "abc" ,與 a 相等。a == b; // true//null和undefined不能夠被封裝(boxed),Object(null)和 Object(undefined) 均返回一個常規對象。var a = null;var b = Object(a); // 和Object()一樣a == b; // falsevar c = undefined;var d = Object(c); // 和Object()一樣c == d; // false//NaN能夠被封裝為數字封裝對象,但NaN不等於NaNvar e = NaN;var f = Object(e); // 和new Number( e )一樣e == f; // false

5)假值的相等比較

假值,就是上面ToBoolean中提到的假值。

"0" == false;//true 按照2)和1)的規則false == 0;//true 按照2)的規則false == "";//true 按照2)和1)的規則false == [];//true 按照4)2)1)的規則"" == 0;//true 按照1)"" == [];//true 按照4)的規則0 == [];//true 按照4)1)的規則[] == ![]// true ![]執行後的值是false

6)安全運用隱式強制類型轉換

1.如果兩邊的值中有true或者false,千萬不要使用==。

2.如果兩邊的值中有[]、0或者"" ,盡量不要使用==。

7)比較圖表

dorey提供的一張線上圖表。




《你不知道的JavaScript》整理(六)——強制類型轉換

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.