JavaScript隱式類型轉(zhuǎn)換例子總結(jié)
前言
熟練掌握類型轉(zhuǎn)換,理解其中的規(guī)律??梢宰屇愕拇a更簡潔更安全。
在編寫代碼的時候,我們通常會有意無意的寫出一些,存在類型轉(zhuǎn)換的代碼。這些代碼有時的返回值總讓人迷惑,比如下列式子都是我們工作中常見的:
var a = 1; var b = '2'; var c = a + b; // '12'; var d = 43; d == '43'; // true d === '43'; // false
上面都是比較常見的,讓我們再看幾個例子:
// 例子1
const obj = {
toString() {
return : 'xxx';
}
}
const obj2 = {};
obj.toString(); // "xxx" 當(dāng)然,我們還是可以使用Object.prototype.toString.call(obj)的,因為這是調(diào)用了Object對象,但是如果改寫了Object的toString方法,那情況就不一樣了。
obj2.toString(); // "[object Object]"
// 例子2
const a = [1,2,3];
const b = [4,5];
a + b; // "1,2,34,5"
// 例子3
false == []; // true
false == ""; // true
false == null; // false
false == undefined; // false
[] == ![]; // true看到上面的結(jié)果,是否你也感覺頭疼?,F(xiàn)在讓我們開始探索,看看這中間都發(fā)生了怎樣的類型轉(zhuǎn)換。
在講強(qiáng)制類型轉(zhuǎn)換是我們先思考一個問題,不同的數(shù)據(jù)類型值都會發(fā)生什么類型轉(zhuǎn)換?在什么情況下會發(fā)生類型轉(zhuǎn)換?具體是怎么轉(zhuǎn)換的?
發(fā)生了類型轉(zhuǎn)換通常都是操作值做了【抽象操作】(ES5規(guī)范第9節(jié)中定義了一些“僅供內(nèi)部使用的操作”)。這里我們簡單介紹一下ToString,ToNumber,ToBoolean同時還有一個ToPrimitive。
ToString
ToString是對非字符串進(jìn)行強(qiáng)制類型轉(zhuǎn)換。
- 對于基本數(shù)據(jù)類型,ToString則是進(jìn)行字符串化,null轉(zhuǎn)化為"null",undefined轉(zhuǎn)化為"undefined",true轉(zhuǎn)化為"true"。對于數(shù)字的ToString,需要注意的是,數(shù)字的極大值跟極小值會轉(zhuǎn)為指數(shù)形式表示。
var a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000; a.toString(); // "1.07e21";
- 對于引用數(shù)據(jù)類型的ToString,通常會調(diào)用引用對象中的 toString()進(jìn)行轉(zhuǎn)化,如果對象沒有這個方法則會發(fā)生報錯。(注意:從ES5開始,使用Objest.create(null)創(chuàng)建的對象,因為創(chuàng)建對象的
[[Prototype]]為null,所以不會有toString()和valueOf()這兩個方法)。
var a = [1,2,3,4];
a.toString(); // "1,2,3,4"
var b = {
a: 42,
foo: 'foo'
}
b.toString(); // "[object Object]"ToNumber
- 對基本數(shù)據(jù)類型,ToNumber跟調(diào)用Number轉(zhuǎn)數(shù)字一樣。
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
Number(""); // 0
Number("123"); // 123
Number("123aaa"); // NaN- 對于引用數(shù)據(jù)類型,會先判斷對象是否有valueOf(),如果有則將返回的值進(jìn)行類型轉(zhuǎn)換。如果沒有,則判斷是否有toSrting(),并將其返回值做類型轉(zhuǎn)換。如果這兩個方法都沒有則報錯TypeError。
var a = { valueOf() { return "42"} };
var b = { toString() { return "42"} };
var c = [1,2];
c.toString = function() { return this.join(""); }
Number(a); // 42
Number(b); // 42
Number(c); // 12
Number([]); // 0
Number([1,2]); // NaNToBoolean
對于抽象操作ToBoolean,ES5規(guī)范9.2中列出一些假值,既對這些值進(jìn)行布爾強(qiáng)制類型轉(zhuǎn)換時,會轉(zhuǎn)為false的值。除了這些值以外,所有值進(jìn)行強(qiáng)制類型轉(zhuǎn)換時,都會得到true。
undefined null "" // 空字符串 +0, -0, NaN false
ToPrimitive
抽象操作ToPrimitive,其實(shí)在ToSting,ToNumber,ToBoolean獲取對象原始值的時候,就是通過ToPrimitive來獲取的,獲取完原始值之后,再進(jìn)行toString(),Number(),Boolean()等類型轉(zhuǎn)換。
總結(jié),在對值進(jìn)行類型轉(zhuǎn)換時,如果是基本數(shù)據(jù)類型,則直接對使用該值進(jìn)行類型轉(zhuǎn)換;如果是引用類型,會先通過ToPrimitive獲取原始值,然后使用獲取的原始值進(jìn)行類型轉(zhuǎn)換。
而之前說的【先檢查對象是否包含valueOf(),如果沒有在檢查toString()】這個過程就是 ToPrimitive。
現(xiàn)在我們分析完類型轉(zhuǎn)換的過程都具體做了什么操作了,現(xiàn)在我們看下,在那些操作下會發(fā)生類型轉(zhuǎn)換。
運(yùn)算符 +
如果操作數(shù)中存在字符串,則進(jìn)行字符串拼接;如果操作數(shù)是對象,則會對對象進(jìn)行 ToPrimitive抽象操作以獲取原始值,通常這操作都會獲取到字符串。最后進(jìn)行 + 操作。
var a = [1,2]; var b = [3,4]; a + b; // "1,23,4"
邏輯判斷相關(guān)
- if(..)
- while(..)和do..while(..)
- 三元表達(dá)式 ?:
- for(..; ..; ..){}
- 邏輯或|| 和 邏輯與&& 左邊的操作數(shù)
上面的語句中所包含的判斷表達(dá)式,都會將非布爾值通過抽象操作ToBoolean,將值轉(zhuǎn)為boolean。
== 寬松對等規(guī)則
1. 字符串和數(shù)字之間的相等比較
- 如果Type(x)是數(shù)字,Type(y)是字符串,則返回 x === ToNumber(y)的結(jié)果。
- 如果Type(x)是字符串,Type(y)是數(shù)字,則返回 ToNumber(x) === y的結(jié)果。
var x = 42;
var y = '42';
x === y; // false
x == y; // true 這里轉(zhuǎn)換為: 42 == ToNumber('42') => true2. 其他類型和布爾類型的相等比較
- 如果Type(x)是布爾類型,則返回 ToNumber(x) === y 的結(jié)果。
- 如果Type(y)是布爾類型,則返回 x === ToNumber(y)的結(jié)果。
var x = true;
var y = '42'
x === y; // false
x == y; // false
// false 這里轉(zhuǎn)換為:toNumber(true) == toNumber('42') => 1 == 42 => false3. null 和 undefined 之間的相等比較
- 如果x為null,y為undefined,則結(jié)果為true。
- 如果x為undefined,y為true,則結(jié)果為true。
注意: 在 == 中null和undefined相等(也與自身相等),除此之外其他值都不和他們相等。 所以可以使用一特性,對值進(jìn)行判斷是否等于null或undefined
var x = null; var y; x === y; // false x == y; //true
4. 對象和非對象之間的相等比較
- 如果Type(x)是字符串或數(shù)字,Type(y)是對象,則返回 x == ToPrimitive(y)的結(jié)果。
- 如果Type(y)是字符串或數(shù)字,Type(x)是對象,則返回 ToPrimitive(x) == y的結(jié)果。
var a = 42 var b = [42] a == b; // true // [42]調(diào)用ToPrimitive,返回"42",變成 "42" == 42,然后又變成 42 == 42,最后兩者相等。 var a = "abc"; var b = Object(a); // new String( a )一樣 a === b; // false a == b; // true
這里有些值不一樣
var a = null; var b = Object(a); // 和Object()一樣 a == b; // false var c = undefined; var d = Object(c); // 和Object()一樣 c == d; // false var e = NaN; var f = Object(e); // 和new Number(e) 一樣 e == f; // NaN == NaN => false
因為js中,沒有undefined 和 null 對應(yīng)的封裝對象。所以對他們進(jìn)行Object封裝跟調(diào)用Object()一樣,返回一個常規(guī)對象。
而NaN是因為,NaN本身就不等于自己。
總結(jié)
總的來說:在寬松對比中,對比的值具有這樣的轉(zhuǎn)換優(yōu)先級,對象 > 非對象(非對象中:字符串,布爾都會ToNumber轉(zhuǎn)為數(shù)字,進(jìn)行比較)。同時需要注意 NaN(唯一不等于自己的值),undefined和null這幾個值的轉(zhuǎn)換。
當(dāng)然,寬松對等中不同值對比,才會進(jìn)行類型轉(zhuǎn)換。如果是相同類型的比較,不會進(jìn)行類型轉(zhuǎn)換。"0" == "" 返回false。因為這是字符串"0"和""的對比,不會進(jìn)行抽象操作ToNumber。
理解了對象的類型轉(zhuǎn)換都是ToPrimitive操作,那么我們需要注意,任何情況下都不要重寫對象的 valueOf()和toString() 方法。
到此這篇關(guān)于JavaScript隱式類型轉(zhuǎn)換例子總結(jié)的文章就介紹到這了,更多相關(guān)JS隱式轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 淺析JavaScript中的隱式類型轉(zhuǎn)換
- JavaScript隱式類型轉(zhuǎn)換
- 總結(jié)Javascript中的隱式類型轉(zhuǎn)換
- 對存在JavaScript隱式類型轉(zhuǎn)換的四種情況的總結(jié)(必看篇)
- JavaScript中運(yùn)算符規(guī)則和隱式類型轉(zhuǎn)換示例詳解
- JS面試題大坑之隱式類型轉(zhuǎn)換實(shí)例代碼
- 有趣的JavaScript隱式類型轉(zhuǎn)換操作實(shí)例分析
- JavaScript隱式類型轉(zhuǎn)換代碼實(shí)例
- 淺析JavaScript中的隱式類型轉(zhuǎn)換
- JavaScript 隱式類型轉(zhuǎn)換規(guī)則詳解
- JS不同運(yùn)算符下隱式類型轉(zhuǎn)換的實(shí)現(xiàn)示例
相關(guān)文章
axios使用攔截器統(tǒng)一處理所有的http請求的方法
這篇文章主要介紹了axios使用攔截器統(tǒng)一處理所有的http請求的方法,通過一段實(shí)例代碼給大家介紹了axios攔截器使用,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-11-11
JavaScript中數(shù)據(jù)結(jié)構(gòu)與算法(一):棧
這篇文章主要介紹了JavaScript中數(shù)據(jù)結(jié)構(gòu)與算法(一):棧,本文講解了棧的結(jié)構(gòu)、什么是回文以及遞歸等內(nèi)容,講解的不錯,通俗易懂,需要的朋友可以參考下2015-06-06
學(xué)習(xí)JavaScript鼠標(biāo)響應(yīng)事件
這篇文章主要帶領(lǐng)大家學(xué)習(xí)JavaScript鼠標(biāo)響應(yīng)事件,為大家分享了一個簡單的鼠標(biāo)模擬案例,感興趣的小伙伴們可以參考一下2015-12-12
layui 點(diǎn)擊重置按鈕, select 并沒有被重置的解決方法
今天小編就為大家分享一篇layui 點(diǎn)擊重置按鈕, select 并沒有被重置的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09

