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

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

一、強(qiáng)制轉(zhuǎn)換為字符串(ToString)

1)ToString

基本類型值的字符串化規(guī)則為:null轉(zhuǎn)換為"null",undefined轉(zhuǎn)換為"undefined",true轉(zhuǎn)換為"true"。數(shù)字的字符串化則遵循通用規(guī)則,不過那些極小和極大的數(shù)字使用指數(shù)形式:

// 1.07 連續(xù)乘以七個(gè) 1000var a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;// 七個(gè)1000一共21位數(shù)字console.log(a.toString()); // "1.07e21"

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

2)JSON

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

如果對(duì)象中定義了toJSON()方法,JSON字符串化時(shí)會(huì)首先調(diào)用該方法,然后用它的返回值來進(jìn)行序列化。

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

 

二、強(qiáng)制轉(zhuǎn)換數(shù)字(ToNumber)

1)ToNumber

1. true轉(zhuǎn)換為1,false轉(zhuǎn)換為0

2. undefined轉(zhuǎn)換為NaN,null轉(zhuǎn)換為0;

3. "",[]轉(zhuǎn)換為0。處理失敗時(shí)返回NaN。

4. ToNumber對(duì)以0開頭的十六進(jìn)制數(shù)并不按十六進(jìn)制處理。

2)對(duì)象

對(duì)象(包括數(shù)組)會(huì)首先被轉(zhuǎn)換為相應(yīng)的基本類型值,如果返回的是非數(shù)字的基本類型值,則再遵循以上規(guī)則將其強(qiáng)制轉(zhuǎn)換為數(shù)字。

為了將值轉(zhuǎn)換為相應(yīng)的基本類型值,抽象操作ToPrimitive會(huì)首先(通過內(nèi)部操作DefaultValue)檢查該值是否有valueOf()方法。

如果有并且返回基本類型值,就使用該值進(jìn)行強(qiáng)制類型轉(zhuǎn)換。如果沒有就使用toString()的返回值(如果存在)來進(jìn)行強(qiáng)制類型轉(zhuǎn)換。

var a = {
  valueOf: function() { //先執(zhí)行valueOf
    return "42";
  }
};var b = {
  toString: function() { //再執(zhí)行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

 

三、強(qiáng)制轉(zhuǎn)換布爾值(ToBoolean)

1)假值(falsy value)

可強(qiáng)制類型轉(zhuǎn)換為false。包括undefined、nullfalse、+0、-0、NaN、""。

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

2)真值

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

[]、{}和function(){}

 

四、顯式強(qiáng)制類型轉(zhuǎn)換

1)奇特的~運(yùn)算符

~x大致等同于-(x+1)。

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

用~~來截除數(shù)字值的小數(shù)部分~~中的第一個(gè)~執(zhí)行ToInt32并反轉(zhuǎn)字位,然后第二個(gè)~再進(jìn)行一次字位反轉(zhuǎn),即將所有字位反轉(zhuǎn)回原值,最后得到的仍然是ToInt32的結(jié)果。

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

2)顯式解析數(shù)字字符串

解析允許字符串中含有非數(shù)字字符,解析按從左到右的順序,如果遇到非數(shù)字字符就停止。

轉(zhuǎn)換不允許出現(xiàn)非數(shù)字字符,否則會(huì)失敗并返回NaN。

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

解析字符串中的浮點(diǎn)數(shù)可以使用 parseFloat(..) 函數(shù)。

非字符串參數(shù)會(huì)首先被強(qiáng)制類型轉(zhuǎn)換為字符串(執(zhí)行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

 

五、隱式強(qiáng)制類型

1)字符串和數(shù)字之間的隱式強(qiáng)制類型轉(zhuǎn)換

如果+其中一個(gè)操作數(shù)是字符串則執(zhí)行字符串拼接;否則執(zhí)行數(shù)字加法。

如果其中一個(gè)操作數(shù)是對(duì)象(包括數(shù)組), 則對(duì)其調(diào)用 ToPrimitive 抽象操作。

var a = "42";var b = "0";
a + b; // "420" 兩個(gè)都是字符串var c = 42;var d = 0;
c + d; // 42 兩個(gè)都是數(shù)字var a = [1, 2];var b = [3, 4];
a + b; // "1,23,4" 兩個(gè)都是對(duì)象

2)隱式強(qiáng)制類型轉(zhuǎn)換為布爾值

以下情況,非布爾值會(huì)被隱式強(qiáng)制類型轉(zhuǎn)換為布爾值,遵循ToBoolean 抽 象操作規(guī)則。

1. if (..)語句中的條件判斷表達(dá)式。

2. for ( .. ; .. ; .. )語句中的條件判斷表達(dá)式(第二個(gè))。

3. while (..)do..while(..)循環(huán)中的條件判斷表達(dá)式。

4. ? :中的條件判斷表達(dá)式。

5.  邏輯運(yùn)算符||(邏輯或)和&&(邏輯與)左邊的操作數(shù)(作為條件判斷表達(dá)式)。

 

六、寬松相等和嚴(yán)格相等

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

正確的解釋是:“ == 允許在相等比較中進(jìn)行強(qiáng)制類型轉(zhuǎn)換,而 === 不允許

1)字符串和數(shù)字之間的相等比較

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

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

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

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

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

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

1.如果 x 為 null , y 為 undefined ,則結(jié)果為 true 。

2.如果 x 為 undefined , y 為 null ,則結(jié)果為 true 。

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

1.如果 Type(x) 是字符串或數(shù)字, Type(y) 是對(duì)象,則返回 x == ToPrimitive(y) 的結(jié)果。

2.如果 Type(x) 是對(duì)象, Type(y) 是字符串或數(shù)字,則返回 ToPromitive(x) == y 的結(jié)果。

var a = "abc";var b = Object(a); // 和new String( a )一樣a === b; // false //b 通過 ToPromitive 進(jìn)行強(qiáng)制類型轉(zhuǎn)換(也稱為“拆封”,unboxed或者unwrapped) ,并返回標(biāo)量基本類型值 "abc" ,與 a 相等。a == b; // true//null和undefined不能夠被封裝(boxed),Object(null)和 Object(undefined) 均返回一個(gè)常規(guī)對(duì)象。var a = null;var b = Object(a); // 和Object()一樣a == b; // falsevar c = undefined;var d = Object(c); // 和Object()一樣c == d; // false//NaN能夠被封裝為數(shù)字封裝對(duì)象,但NaN不等于NaNvar e = NaN;var f = Object(e); // 和new Number( e )一樣e == f; // false

5)假值的相等比較

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

"0" == false;//true 按照2)和1)的規(guī)則false == 0;//true 按照2)的規(guī)則false == "";//true 按照2)和1)的規(guī)則false == [];//true 按照4)2)1)的規(guī)則"" == 0;//true 按照1)"" == [];//true 按照4)的規(guī)則0 == [];//true 按照4)1)的規(guī)則[] == ![]// true ![]執(zhí)行后的值是false

6)安全運(yùn)用隱式強(qiáng)制類型轉(zhuǎn)換

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

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

7)比較圖表

dorey提供的一張在線圖表。

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營(yíng)銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營(yíng)銷培訓(xùn)

http://www.cnblogs.com/strick/p/6440147.html