Javascript基礎(chǔ)之-強(qiáng)制類(lèi)型轉(zhuǎn)換(三)

這一節(jié),應(yīng)該算是強(qiáng)制類(lèi)型轉(zhuǎn)換的最后一個(gè)小節(jié)了呼渣,這一部分呢擂橘,主要會(huì)講比較操作中遇到的強(qiáng)制類(lèi)型轉(zhuǎn)換晌区。


抽象相等(==)和嚴(yán)格相等(===)。

簡(jiǎn)單且粗略的來(lái)說(shuō)通贞,抽象相等和嚴(yán)格相等的區(qū)別就是抽象相等在比較的時(shí)候朗若,如果比較的兩個(gè)數(shù)類(lèi)型不同,會(huì)先進(jìn)行類(lèi)型轉(zhuǎn)換再比較昌罩,而嚴(yán)格類(lèi)型呢哭懈,比較簡(jiǎn)單粗暴一些,直接返回false茎用。

當(dāng)然啦遣总,你也可以這么理解你虹,抽象比較的時(shí)候,允許類(lèi)型轉(zhuǎn)換彤避,而嚴(yán)格相等則不允許,所以看如下例子:


console.log('1111' == 1111)? // true

console.log('1111' === 1111)? // false

這個(gè)例子很容易理解夯辖,那么本例中琉预,抽象相等中究竟是從字符串轉(zhuǎn)換為數(shù)字呢,還是相反蒿褂?


規(guī)范是這么說(shuō)的:

如果相比較的兩個(gè)操作數(shù)圆米,其中一個(gè)是數(shù)字類(lèi)型,另一個(gè)是字符串類(lèi)型的話啄栓,那么字符串將會(huì)轉(zhuǎn)換為數(shù)字娄帖,再進(jìn)行比較,就相等于:

console.log(Number('1111') == 1111);


那么如果是布爾值呢昙楚?比如說(shuō)

console.log("42" == true);? // false

console.log(12 == true);? // false

console.log(-1 == true);? // false

哇哦近速,都是false呀,是不是和一開(kāi)始的認(rèn)知不太一樣呢堪旧?尤其是對(duì)于有其他語(yǔ)言基礎(chǔ)的童鞋們削葱。

這一方面ecma規(guī)范也有說(shuō)了:

如果操作數(shù)中,有布爾類(lèi)型的淳梦,那么他將會(huì)轉(zhuǎn)為數(shù)字類(lèi)型析砸,再進(jìn)行比較。


大家請(qǐng)看著個(gè)例子爆袍,應(yīng)該不用多說(shuō)了吧首繁,上面說(shuō)過(guò)了,嚴(yán)格相等的話陨囊,如果類(lèi)型不一樣弦疮,直接返回false,畢竟人家是嚴(yán)格相等谆扎,很?chē)?yán)格的挂捅。

console.log(false === 0); // false

console.log(false == 0); // true


那么如果null和undefined比較呢?

console.log(null == null); // true

console.log(undefined == null); // true

console.log(undefined == undefined) // true

第一個(gè)和第三個(gè)大家比較容易理解堂湖,第二個(gè)可能比較疑惑闲先,為甚呢?

因?yàn)橐?guī)范上有說(shuō)无蜂,如果比較的兩種伺糠,一個(gè)是undefined另一種是null,則返回true斥季,但是這個(gè)也只是對(duì)應(yīng)于抽象相等训桶,嚴(yán)格相等時(shí)不可能相等的累驮。因?yàn)轭?lèi)型不一樣。


至于上面那個(gè)呢舵揭,我還應(yīng)該多說(shuō)一句谤专,除了undefined和null比較或者是他們同類(lèi)型的比較是true,和其他任何類(lèi)型的值比較都是false午绳,有一些看起來(lái)像true的置侍,結(jié)果都是false,要注意一下拦焚。

console.log(null == false); // false

console.log(undefined == 0); // false

console.log(undefined == "") // false


接下來(lái)這個(gè)比較重要了蜡坊,就是對(duì)象和非對(duì)象的比較。

先看規(guī)范定義吧:

對(duì)于兩個(gè)操作數(shù)赎败,如果其中一個(gè)是字符串或數(shù)字秕衙,另一個(gè)是對(duì)象的話,那么對(duì)象會(huì)轉(zhuǎn)為原始值僵刮,然后再進(jìn)行比較据忘。


那么怎么獲取原始值呢?

其實(shí)其他小節(jié)也都講過(guò)搞糕,這里在復(fù)述一下若河,簡(jiǎn)單來(lái)說(shuō),就是先調(diào)用對(duì)象的valueOf()函數(shù)寞宫,如果它不存在萧福,或者不會(huì)轉(zhuǎn)為基本類(lèi)型值,就調(diào)用toString()函數(shù)辈赋,如果toString()不存在或者返回的是非字符串的值鲫忍,將會(huì)直接報(bào)錯(cuò)。

看起來(lái)有一點(diǎn)枯燥吧钥屈,那么看例子悟民。

console.log([2].valueOf());? // [2]

console.log([2].toString());? // "2"

console.log([2].toString() == 2);? // true

數(shù)組[2]呢,可以看到篷就,他的valueOf返回的是一個(gè)數(shù)組射亏,那么他就會(huì)用toString(),轉(zhuǎn)為字符串“2”竭业,字符串2和數(shù)字2比較呢智润,根據(jù)上面講的,字符串2會(huì)變?yōu)閿?shù)字2未辆,相等窟绷,返回true。


在看一個(gè)例子

var obj = {

valueOf() {

return 3;

}

}

console.log(obj == 3);? // true

var obj1 = Object.create(null);

console.log(obj1 == 3);? // Uncaught TypeError: Cannot convert object to primitive value

這個(gè)呢咐柜,就是對(duì)象先調(diào)用valueOf()得到基本類(lèi)型值3兼蜈,然后再進(jìn)行比較得到true攘残,第二個(gè)呢,得到了一個(gè)純凈的對(duì)象(沒(méi)有prototype),然后獲取不到valueOf()和toString()为狸,直接報(bào)錯(cuò)了歼郭。


那其他的情況呢

console.log(NaN == NaN);? // false

console.log(NaN === NaN);? // false

console.log(+0 == -0);? // true

console.log(+0 === -0);? // true

console.log({} == {});? // false

console.log({} === {});? // false

var obj1 = obj = {};

console.log(obj == obj1);? // true

console.log(obj === obj1);? // true

這個(gè)分析一下,規(guī)范中:

NaN不等于自身辐棒,+0和-0是相等的实撒,對(duì)象是否相等是根據(jù)是否引用同一對(duì)象。


對(duì)象相等的已經(jīng)介紹完了涉瘾,那么判斷不相等的呢?比如說(shuō)(!=)和(!==)他們的區(qū)別呢

實(shí)際上捷兰,他們的語(yǔ)法判斷規(guī)則和相等的規(guī)則一樣立叛,只不過(guò)最后多了一個(gè)置反的一個(gè)步驟。也就是!(a == b)或者是!(a === b)贡茅,我感覺(jué)應(yīng)該很容易理解秘蛇,就不舉例了。


那么最后就要講關(guān)系操作符了顶考,也就是大于小于這些的赁还。


那么我們先講兩個(gè)操作符中,有至少是一個(gè)數(shù)字的情況驹沿。請(qǐng)看下面的例子

console.log(1 < 2);? // true

console.log("0b1" < 2);? // true

var obj = {

valueOf() {

return 1;

}

}

console.log(obj < 2);? // true

console.log(1 < Infinity);? // true

console.log(-Infinity < 1);? // true

console.log(NaN > 1);? // false

console.log(NaN < 1);? // false

上面這幾個(gè)例子艘策,幾乎涵蓋了規(guī)范中至少有一個(gè)操作數(shù)是數(shù)字的比較的情況。

首先渊季,也是如果有對(duì)象的話朋蔫,會(huì)把對(duì)象轉(zhuǎn)為基本類(lèi)型值,在進(jìn)行比較却汉。

并且如果另一個(gè)操作數(shù)是字符串的話驯妄,會(huì)把字符串轉(zhuǎn)成數(shù)字。

還有就是數(shù)字一直小于正無(wú)窮合砂,大于負(fù)無(wú)窮青扔。

NaN無(wú)論怎么判斷都是false。


那么如果是字符串之間的比較呢翩伪,也就是倆操作數(shù)都是字符串的情況微猖。


console.log("1003" > "2");? // false

嗯,很簡(jiǎn)單是吧缘屹,如果倆都是字符串的話励两,實(shí)際上會(huì)按照字母順序去比,這樣去排出哪個(gè)值囊颅。

那么是怎么按照字母順序比的呢当悔,字母順序又是通過(guò)什么方式取得的呢傅瞻?請(qǐng)看例子:

console.log("aaa" > "aa"); // true

console.log("1003" > "2");? // false

console.log("a" > "b");? // false

console.log('&' < "a");? // true

console.log("A" < "a");? // true

console.log("a".charCodeAt());? // 97

console.log("b".charCodeAt());? // 98

console.log("&".charCodeAt());? // 38

console.log("A".charCodeAt());? // 65

這個(gè)例子,應(yīng)該就很容易理解了盲憎,實(shí)際上取的是字符串的charCodeAt()嗅骄,實(shí)際上你依然可以理解為轉(zhuǎn)換成數(shù)字去比了,只不過(guò)字符串的比和含有數(shù)字的比是不一樣的饼疙,數(shù)字的比意味著他們整體數(shù)字的值的大小去比溺森,而字符串是比從一開(kāi)始的前綴挨個(gè)比每個(gè)字母的大小。


是不是依然比較好理解窑眯,那么在來(lái)一個(gè)例子屏积。

var a = [ 42 ];

var b = "043";

console.log(a < b);? // false

console.log(Number(a) < Number(b)); // true

這個(gè)結(jié)合上面那個(gè)規(guī)則,自己分析下磅甩。


最后的最后炊林,我們看一個(gè)你可能略感疑惑的例子:

var a = { b: 42 };

var b = { b: 43 };

console.log(a < b);? // false

console.log(a == b); // false

console.log(a > b);? // false

console.log(a <= b);? // true

console.log(a >= b);? // true

這個(gè)例子,確實(shí)不太付合常識(shí)呀卷要,但是呢渣聚,這確實(shí)是存在的,我給解釋一下僧叉。

首先呢奕枝,a < b和a > b,由于他們倆都是對(duì)象瓶堕,所以轉(zhuǎn)換為基本類(lèi)型值后為字符串“[object Object]”隘道,所以返回false,而a == b呢郎笆,則是因?yàn)樗麄z并不是同一個(gè)對(duì)象的不同的引用薄声,所以返回false。

最后倆呢题画,實(shí)際上大于等于或者小于等于可以理解為大于或者小于的值的反值默辨,也就是: !(a <= b),所以前面為false苍息,反一下為true


好啦缩幸,三個(gè)小章基本把強(qiáng)制類(lèi)型轉(zhuǎn)換整個(gè)梳理了一遍,因?yàn)檫@一塊的細(xì)節(jié)太多竞思,所以說(shuō)呢表谊,我反倒是建議讀到我這里的小伙伴,先把大體規(guī)則了解以后盖喷,特別細(xì)節(jié)的規(guī)則爆办,用到的時(shí)候看看我的小散文,或者直接去看ecma262標(biāo)準(zhǔn)文檔也行课梳,但是呢距辆,強(qiáng)調(diào)一點(diǎn)就是余佃,假如真的要用之前,還是建議自己吧代碼跑一下跨算,這樣我的感觸就是要比只看效果好太多爆土。


總之感謝大家收看我的小散文。


參考書(shū)籍《你不知道的Javascript中卷》

參考文檔:ECMAScript 5.1(ECMA-262)

https://www.ecma-international.org/ecma-262/5.1/

本文轉(zhuǎn)載自http://www.lht.ren/article/7/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诸蚕,一起剝皮案震驚了整個(gè)濱河市步势,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌背犯,老刑警劉巖坏瘩,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異漠魏,居然都是意外死亡倔矾,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)蛉幸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人丛晦,你說(shuō)我怎么就攤上這事奕纫。” “怎么了烫沙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵匹层,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锌蓄,道長(zhǎng)升筏,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任瘸爽,我火速辦了婚禮您访,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剪决。我一直安慰自己灵汪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布拼余。 她就那樣靜靜地躺著恕刘,像睡著了一般勘究。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上览露,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音譬胎,去河邊找鬼差牛。 笑死命锄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的多糠。 我是一名探鬼主播累舷,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼夹孔!你這毒婦竟也來(lái)了被盈?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤搭伤,失蹤者是張志新(化名)和其女友劉穎只怎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體怜俐,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡身堡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拍鲤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贴谎。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖季稳,靈堂內(nèi)的尸體忽然破棺而出擅这,到底是詐尸還是另有隱情,我是刑警寧澤景鼠,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布仲翎,位于F島的核電站,受9級(jí)特大地震影響铛漓,放射性物質(zhì)發(fā)生泄漏溯香。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一浓恶、第九天 我趴在偏房一處隱蔽的房頂上張望玫坛。 院中可真熱鬧,春花似錦包晰、人聲如沸昂秃。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)肠骆。三九已至,卻和暖如春塞耕,著一層夾襖步出監(jiān)牢的瞬間蚀腿,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莉钙,地道東北人廓脆。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像磁玉,于是被迫代替她去往敵國(guó)和親停忿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容