摘要:如果有并且返回基本類型值,再使用該值進行強制類型轉換。四寬松相等和嚴格相等允許在相等比較中進行強制類型轉換,而不允許。這時最好用來避免不經意的強制類型轉換。這兩個原則可以讓我們避開幾乎所有強制類型轉換的坑。
一、類型轉換規則 1.ToString
對于普通對象來說,除非自行定義toString方法,否則就會調用Object.prototype.toString()方法,如果對象有自己的toString方法,字符串化就會調用該方法并使用其返回值。
2.ToNumber對于基本類型其中true轉換為1,false轉換為0;undefined 轉換為 NaN,null 轉換為 0。
對于對象類型會首先轉換成為基本類型值如果返回的是非數字的基本類型值,則再遵循基本類型轉換規則將其強制轉換為數字。為了將值轉換為相應的基本類型值,抽象操作ToPrimitive會首先檢查該值是否有 valueOf() 方法。如果有并且返回基本類型值,再使用該值進行強制類型轉換。如果沒有就使用 toString() 的返回值(如果存在)來進行強制類型轉換。如果 valueOf() 和 toString() 均不返回基本類型值,會產生 TypeError 錯誤。
let a = { valueOf:function(){ return "42"; } }; let b = { toString:function(){ return "42"; } }; let c = [4,2]; c.toString = function(){ return this.join(""); //"42" }; Number(a); //42 Number(b); //42 Number(c); //42 Number(""); //0 Number([]); //0 Number(["abc"];//NaN3.ToBoolean
JavaScript中的值可以分為能被強制轉換為false的值和能被強制轉換為true的值兩類。
假值:
undefined
null
false
+0、-0、NaN
""
真值:除了以上列表的都可以理解為是真值,所有對象都是真值
let a1 = new Boolean( false ); let b1 = new Number( 0 ); let c1 = new String( "" ); let d1 = Boolean(a1 && b1 && c1); //true let a2 = []; let b2 = {}; let c2 = function(){}; let d2 = Boolean(a2 && b2 && c2); //true二、顯示強制類型轉換 1.字符串與數字之間的顯示轉換
字符串和數字之間的轉換是通過 String(..) 和 Number(..) 這兩個內建函數。
除了 String(..) 和 Number(..) 以外,還有其他方法可以實現字符串和數字之間的顯式 轉換:
let a = 42; let b = a.toString(); let c = "3.14"; let d = +c; b; // "42" d; // 3.14
a.toString() 是顯式的,不過其中涉及隱式轉換。因為 toString() 對 42 這樣的基本類型值不適用,所以 JavaScript 引擎會自動為 42 創建一個封裝對象,然后對該對象調用 toString()。這里顯式轉換中含有隱式轉換。
2.顯示轉換為布爾值let a = "0"; let b = []; let c = {}; let d = ""; let e = 0; let f = null; let g; Boolean( a ); // true Boolean( b ); // true Boolean( c ); // true Boolean( d ); // false Boolean( e ); // false Boolean( f ); // false Boolean( g ); // false
雖然 Boolean(..) 是顯式的,但并不常用。顯式強制類型轉換為布爾值最常用的方法是 !!
let a = "0"; let b = []; let c = {}; let d = ""; let e = 0; let f = null; let g; !!a; // true !!b; // true !!c; // true !!d; // false !!e; // false !!f; // false !!g; // false三、隱式強制類型轉換 1.字符串和數字之間的隱式強制類型轉換 (1)+運算符
即能用于數字加法,也能用于字符串拼接
如果 + 的其中一個操作數是字符串(或者通過對其調用 ToPrimitive 抽象操作得到字符串), 則執行字符串拼接;否則執行數字加法。因為數組的 valueOf() 操作無法得到簡單基本類型值,于是它轉而調用 toString()。因此下例中的兩個數組變成了 "1,2" 和 "3,4"。+ 將它們拼接后返回 "1,23,4"。
let a = "42"; let b = "0"; a + b; // "420" let c = 42; let d = 0; c + d; // 42 let x = [1,2]; let y = [3,4]; x + y; // "1,23,4"可以使用+運算符進行字符串轉換,將數字和空字符串 "" 相 + 來將其轉換為字符串
let a = 42; let b = a + ""; b; // "42"a + ""(隱式)和前面的String(a)(顯式)之間有一個細微的差別需要注意。
根據 ToPrimitive抽象操作規則,a + ""會對a調用valueOf()方法,然后通過ToString抽象 操作將返回值轉換為字符串。而 String(a) 則是直接調用 ToString()。它們最后返回的都是字符串,但如果 a 是對象而非數字結果可能會不一樣
let a = { valueOf: function() { return 42; }, toString: function() { return 4; } }; a + ""; // "42" String( a ); // "4"(2)從字符串強制類型轉換為數字的情況
-是數字減法運算符,因此a - 0會將a強制類型轉換為數字。也可以使用a * 1和a /1,因為這兩個運算符也只適用于數字,只不過這樣的用法不太常見
let a = [3]; let b = [1]; a - b; // 22.隱式強制類型轉換為布爾值
下面的情況會發生 布爾值隱式強制類型轉換:
(1) if (..)語句中的條件判斷表達式。
(2) for ( .. ; .. ; .. )語句中的條件判斷表達式(第二個)。
(3) while (..) 和 do..while(..) 循環中的條件判斷表達式。
(4) ? :中的條件判斷表達式。
(5) 邏輯運算符 ||(邏輯或)和 &&(邏輯與)左邊的操作數(作為條件判斷表達式)。
以上情況中,非布爾值會被隱式強制類型轉換為布爾值,遵循前面介紹過的 ToBoolean 抽象操作規則。
四、寬松相等和嚴格相等== 允許在相等比較中進行強制類型轉換,而 === 不允許。== 和 === 都會檢查操作數的類型。區別在于操作數類型不同時它們的處理方式不同。
1.字符串和數字之間的相等比較let a = 42; let b = "42"; a === b; // false a == b; // true
因為===沒有強制類型轉換,所以 a === b 為 false,42 和 "42" 不相等。而 a == b 是寬松相等,即如果兩個值的類型不同,則對其中之一或兩者都進行強制類型轉換。
轉換規則如下:
(1) 如果 Type(x) 是數字,Type(y) 是字符串,則返回 x == ToNumber(y) 的結果。
(2) 如果 Type(x) 是字符串,Type(y) 是數字,則返回 ToNumber(x) == y 的結果。
let a = "42"; let b = true; a == b; // false
轉換規則如下:
(1) 如果 Type(x) 是布爾類型,則返回 ToNumber(x) == y 的結果;
(2) 如果 Type(y) 是布爾類型,則返回 x == ToNumber(y) 的結果。
上例中Type(x)是布爾值,所以ToNumber(x)將true強制類型轉換為1,變成1 == "42",二者的類型仍然不同,"42" 根據規則被強制類型轉換為 42,最后變成 1 == 42,結果為 false。
3.null和undefined之間的相等比較(1) 如果 x 為 null,y 為 undefined,則結果為 true。
(2) 如果 x 為 null,y 不是?undefined或者null,則結果為 false。
(3) 如果 x 為 undefined,y 為 null,則結果為 true。
(4)如果 x 為 undefined,y 不是?undefined或者null,則結果為 false。
let a = null; let b; a == b; // true a == null; // true b == null; // true a == false; // false b == false; // false a == ""; // false b == ""; // false a == 0; // false b == 0; // false4.對象和非對象之間的相等比較
(1) 如果 Type(x) 是字符串或數字,Type(y) 是對象,則返回 x == ToPrimitive(y) 的結果;
(2) 如果 Type(x) 是對象,Type(y) 是字符串或數字,則返回 ToPromitive(x) == y 的結果。
let a = 42; var b = [ 42 ]; a == b; // true
[ 42 ] 首先調用 ToPromitive 抽象操作,返回 "42",變成 "42" == 42,然后 又變成 42 == 42,最后二者相等
5.比較少見的情況 (1)假值的相等比較"0" == null; // false "0" == undefined; // false "0" == false; // true -- "0" == NaN; // false "0" == 0; // true "0" == ""; // false false == null; // false false == undefined; // false false == NaN; // false false == 0; // true -- false == ""; // true -- false == []; // true -- false == {}; // false "" == null; // false "" == undefined; // false "" == NaN; // false "" == 0; // true -- "" == []; // true -- "" == {}; // false 0 == null; // false 0 == undefined; // false 0 == NaN; // false 0 == []; // true -- 0 == {}; // false(2)安全運用隱式強制類型轉換
如果兩邊的值中有 true 或者 false,千萬不要使用 ==
如果兩邊的值中有 []、"" 或者 0,盡量不要使用 ==。
這時最好用 === 來避免不經意的強制類型轉換。這兩個原則可以讓我們避開幾乎所有強制 類型轉換的坑。
五、Object.is(..) 判斷兩個值是否相等以下情況返回true:
兩個值都是 undefined
兩個值都是 null
兩個值都是 true 或者都是 false
兩個值是由相同個數的字符按照相同的順序組成的字符串
兩個值指向同一個對象
兩個值都是數字并且
都是正零 +0
都是負零 -0
都是 NaN
都是除零和 NaN 外的其它同一個數字
對于 ES6 之前的版本,Object.is(..) 有一個簡單的 polyfill:
if (!Object.is) { Object.is = function(v1, v2) { // 判斷是否是-0 if (v1 === 0 && v2 === 0) { return 1 / v1 === 1 / v2; } // 判斷是否是NaN if (v1 !== v1) { return v2 !== v2; } // 其他情況 return v1 === v2; }; }
參考文章:
JavaScript高級程序設計
你不知道的JavaScript(中卷)
? ? ?
? ? ?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98457.html
摘要:抽象相等和嚴格相等。首先,也是如果有對象的話,會把對象轉為基本類型值,在進行比較。 這一節,應該算是強制類型轉換的最后一個小節了,這一部分呢,主要會講比較操作中遇到的強制類型轉換。 抽象相等(==)和嚴格相等(===)。 簡單且粗略的來說,抽象相等和嚴格相等的區別就是抽象相等在比較的時候,如果比較的兩個數類型不同,會先進行類型轉換再比較,而嚴格類型呢,比較簡單粗暴一些,直接返回fals...
摘要:顯示的調用轉換過程稱為顯式強制類型轉換,隱式的情況稱為隱式強制類型轉換。隱式強制類型轉換讓代碼變得晦澀難懂而又便捷而奇妙。事實上,允許在比較中進行強制類型轉換,而不允許。如果有并且返回基本類型值,就使用該值進行強制類型轉換。 JavaScript是一種非常靈活的現代編程語言,靈活到使用者極其容易被忽視的它那廣闊的世界以及它帶給我們的無限遐想空間。本文將對JavaScript最最基礎也最...
摘要:轉換為字符串規則如下圖代碼大致就是普通其他基本類型轉為字符串的話,就直接轉為其值的字符串表達形式,如果是基本類型的封裝對象,會先拆封,然后再轉為字符串,如果是普通對象,則會調用其內部的值,如果是極大數和級小數,將會進行一些轉化,具體規 轉換為字符串規則如下圖代碼: console.log(String(undefined)); // undefined console.log(Str...
摘要:一返回值調用外部方法獲取的值需要對類型做判斷,因為我們對方法返回的值是有期望值類型,但是卻不能保證這個接口返回的值一直是同一個類型。 19年目標:消滅英語!我新開了一個公眾號記錄一個程序員學英語的歷程 有提升英語訴求的小伙伴可以關注公眾號:csenglish 程序員學英語,每天花10分鐘交作業,跟我一起學英語吧 javascript作為一門動態類型語言,具有很高的動態靈活性,當定義函數...
摘要:所以無論還是都會進行類型轉換,唯一的區別,就是會置否而不會。這時候,肯定會有人問,假如說我有其他的數據類型呢,又不是數字又不是字符串,比如說數組啊,對象啊,布爾值啥的,那么如果是引用數據類型,則先轉為基本數據類型,再進行比較。 上一章主要講了轉換到數字,字符串和布爾類型的一些知識點,那么這一講接著上面的繼續講。 思考下面這個問題: console.log(+123); // 123 ...
閱讀 3069·2021-11-24 11:14
閱讀 3480·2021-11-22 15:22
閱讀 3200·2021-09-27 13:36
閱讀 712·2021-08-31 14:29
閱讀 1328·2019-08-30 15:55
閱讀 1752·2019-08-29 17:29
閱讀 1143·2019-08-29 16:24
閱讀 2400·2019-08-26 13:48