摘要:抽象相等和嚴(yán)格相等。首先,也是如果有對(duì)象的話,會(huì)把對(duì)象轉(zhuǎn)為基本類型值,在進(jìn)行比較。
這一節(jié),應(yīng)該算是強(qiáng)制類型轉(zhuǎn)換的最后一個(gè)小節(jié)了,這一部分呢,主要會(huì)講比較操作中遇到的強(qiáng)制類型轉(zhuǎn)換。
抽象相等(==)和嚴(yán)格相等(===)。
簡(jiǎn)單且粗略的來(lái)說(shuō),抽象相等和嚴(yán)格相等的區(qū)別就是抽象相等在比較的時(shí)候,如果比較的兩個(gè)數(shù)類型不同,會(huì)先進(jìn)行類型轉(zhuǎn)換再比較,而嚴(yán)格類型呢,比較簡(jiǎn)單粗暴一些,直接返回false。
當(dāng)然啦,你也可以這么理解,抽象比較的時(shí)候,允許類型轉(zhuǎn)換,而嚴(yán)格相等則不允許,所以看如下例子:
console.log("1111" == 1111) // true console.log("1111" === 1111) // false
這個(gè)例子很容易理解,那么本例中,抽象相等中究竟是從字符串轉(zhuǎn)換為數(shù)字呢,還是相反?
規(guī)范是這么說(shuō)的:
如果相比較的兩個(gè)操作數(shù),其中一個(gè)是數(shù)字類型,另一個(gè)是字符串類型的話,那么字符串將會(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ù)中,有布爾類型的,那么他將會(huì)轉(zhuǎn)為數(shù)字類型,再進(jìn)行比較。
大家請(qǐng)看著個(gè)例子,應(yīng)該不用多說(shuō)了吧,上面說(shuō)過(guò)了,嚴(yán)格相等的話,如果類型不一樣,直接返回false,畢竟人家是嚴(yán)格相等,很嚴(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)轭愋筒灰粯印?/p>
至于上面那個(gè)呢,我還應(yīng)該多說(shuō)一句,除了undefined和null比較或者是他們同類型的比較是true,和其他任何類型的值比較都是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)為基本類型值,就調(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()得到基本類型值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)為基本類型值,在進(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)換為基本類型值后為字符串“[object Object]”,所以返回false,而a == b呢,則是因?yàn)樗麄z并不是同一個(gè)對(duì)象的不同的引用,所以返回false。
最后倆呢,實(shí)際上大于等于或者小于等于可以理解為大于或者小于的值的反值,也就是: !(a <= b),所以前面為false,反一下為true
好啦,三個(gè)小章基本把強(qiáng)制類型轉(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-internationa...
本文轉(zhuǎn)載自http://www.lht.ren/article/7/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/100726.html
摘要:所以無(wú)論還是都會(huì)進(jìn)行類型轉(zhuǎn)換,唯一的區(qū)別,就是會(huì)置否而不會(huì)。這時(shí)候,肯定會(huì)有人問(wèn),假如說(shuō)我有其他的數(shù)據(jù)類型呢,又不是數(shù)字又不是字符串,比如說(shuō)數(shù)組啊,對(duì)象啊,布爾值啥的,那么如果是引用數(shù)據(jù)類型,則先轉(zhuǎn)為基本數(shù)據(jù)類型,再進(jìn)行比較。 上一章主要講了轉(zhuǎn)換到數(shù)字,字符串和布爾類型的一些知識(shí)點(diǎn),那么這一講接著上面的繼續(xù)講。 思考下面這個(gè)問(wèn)題: console.log(+123); // 123 ...
摘要:轉(zhuǎn)換為字符串規(guī)則如下圖代碼大致就是普通其他基本類型轉(zhuǎn)為字符串的話,就直接轉(zhuǎn)為其值的字符串表達(dá)形式,如果是基本類型的封裝對(duì)象,會(huì)先拆封,然后再轉(zhuǎn)為字符串,如果是普通對(duì)象,則會(huì)調(diào)用其內(nèi)部的值,如果是極大數(shù)和級(jí)小數(shù),將會(huì)進(jìn)行一些轉(zhuǎn)化,具體規(guī) 轉(zhuǎn)換為字符串規(guī)則如下圖代碼: console.log(String(undefined)); // undefined console.log(Str...
摘要:前綴規(guī)范每個(gè)局部變量都需要有一個(gè)類型前綴,按照類型可以分為表示字符串。例如,表示以上未涉及到的其他對(duì)象,例如,表示全局變量,例如,是一種區(qū)分大小寫(xiě)的語(yǔ)言。布爾值與字符串相加將布爾值強(qiáng)制轉(zhuǎn)換為字符串。 基本概念 javascript是一門解釋型的語(yǔ)言,瀏覽器充當(dāng)解釋器。js執(zhí)行時(shí),在同一個(gè)作用域內(nèi)是先解釋再執(zhí)行。解釋的時(shí)候會(huì)編譯function和var這兩個(gè)關(guān)鍵詞定義的變量,編譯完成后從...
摘要:一返回值調(diào)用外部方法獲取的值需要對(duì)類型做判斷,因?yàn)槲覀儗?duì)方法返回的值是有期望值類型,但是卻不能保證這個(gè)接口返回的值一直是同一個(gè)類型。 19年目標(biāo):消滅英語(yǔ)!我新開(kāi)了一個(gè)公眾號(hào)記錄一個(gè)程序員學(xué)英語(yǔ)的歷程 有提升英語(yǔ)訴求的小伙伴可以關(guān)注公眾號(hào):csenglish 程序員學(xué)英語(yǔ),每天花10分鐘交作業(yè),跟我一起學(xué)英語(yǔ)吧 javascript作為一門動(dòng)態(tài)類型語(yǔ)言,具有很高的動(dòng)態(tài)靈活性,當(dāng)定義函數(shù)...
摘要:實(shí)際上,我們通常認(rèn)為是自有類型的唯一成員。比較運(yùn)算符的操作數(shù)可能是任意類型。結(jié)果只有,例得到操作值等價(jià)的布爾值真值為,假值為等同于,經(jīng)常稱為強(qiáng)制轉(zhuǎn)換。結(jié)果返回布爾值的用法是中唯一一個(gè)不等于任何值的包括它自己。 說(shuō)起 js 類型轉(zhuǎn)換,都是頭疼吧,暈暈的,但是不行啊,這東西很重要滴! 基礎(chǔ)知識(shí) JavaScript的數(shù)據(jù)類型分為六種,分別為null, undefined, boolean,...
閱讀 1008·2021-10-27 14:15
閱讀 2763·2021-10-25 09:45
閱讀 1921·2021-09-02 09:45
閱讀 3357·2019-08-30 15:55
閱讀 1798·2019-08-29 16:05
閱讀 3189·2019-08-28 18:13
閱讀 3109·2019-08-26 13:58
閱讀 442·2019-08-26 12:01