摘要:抽象相等和嚴(yán)格相等。首先,也是如果有對象的話,會把對象轉(zhuǎn)為基本類型值,在進(jìn)行比較。
這一節(jié),應(yīng)該算是強(qiáng)制類型轉(zhuǎn)換的最后一個小節(jié)了,這一部分呢,主要會講比較操作中遇到的強(qiáng)制類型轉(zhuǎn)換。
抽象相等(==)和嚴(yán)格相等(===)。
簡單且粗略的來說,抽象相等和嚴(yán)格相等的區(qū)別就是抽象相等在比較的時候,如果比較的兩個數(shù)類型不同,會先進(jìn)行類型轉(zhuǎn)換再比較,而嚴(yán)格類型呢,比較簡單粗暴一些,直接返回false。
當(dāng)然啦,你也可以這么理解,抽象比較的時候,允許類型轉(zhuǎn)換,而嚴(yán)格相等則不允許,所以看如下例子:
console.log("1111" == 1111) // true console.log("1111" === 1111) // false
這個例子很容易理解,那么本例中,抽象相等中究竟是從字符串轉(zhuǎn)換為數(shù)字呢,還是相反?
規(guī)范是這么說的:
如果相比較的兩個操作數(shù),其中一個是數(shù)字類型,另一個是字符串類型的話,那么字符串將會轉(zhuǎn)換為數(shù)字,再進(jìn)行比較,就相等于:
console.log(Number("1111") == 1111);
那么如果是布爾值呢?比如說
console.log("42" == true); // false console.log(12 == true); // false console.log(-1 == true); // false
哇哦,都是false呀,是不是和一開始的認(rèn)知不太一樣呢?尤其是對于有其他語言基礎(chǔ)的童鞋們。
這一方面ecma規(guī)范也有說了:
如果操作數(shù)中,有布爾類型的,那么他將會轉(zhuǎn)為數(shù)字類型,再進(jìn)行比較。
大家請看著個例子,應(yīng)該不用多說了吧,上面說過了,嚴(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
第一個和第三個大家比較容易理解,第二個可能比較疑惑,為甚呢?
因為規(guī)范上有說,如果比較的兩種,一個是undefined另一種是null,則返回true,但是這個也只是對應(yīng)于抽象相等,嚴(yán)格相等時不可能相等的。因為類型不一樣。
至于上面那個呢,我還應(yīng)該多說一句,除了undefined和null比較或者是他們同類型的比較是true,和其他任何類型的值比較都是false,有一些看起來像true的,結(jié)果都是false,要注意一下。
console.log(null == false); // false console.log(undefined == 0); // false console.log(undefined == "") // false
接下來這個比較重要了,就是對象和非對象的比較。
先看規(guī)范定義吧:
對于兩個操作數(shù),如果其中一個是字符串或數(shù)字,另一個是對象的話,那么對象會轉(zhuǎn)為原始值,然后再進(jìn)行比較。
那么怎么獲取原始值呢?
其實(shí)其他小節(jié)也都講過,這里在復(fù)述一下,簡單來說,就是先調(diào)用對象的valueOf()函數(shù),如果它不存在,或者不會轉(zhuǎn)為基本類型值,就調(diào)用toString()函數(shù),如果toString()不存在或者返回的是非字符串的值,將會直接報錯。
看起來有一點(diǎn)枯燥吧,那么看例子。
console.log([2].valueOf()); // [2] console.log([2].toString()); // "2" console.log([2].toString() == 2); // true
數(shù)組[2]呢,可以看到,他的valueOf返回的是一個數(shù)組,那么他就會用toString(),轉(zhuǎn)為字符串“2”,字符串2和數(shù)字2比較呢,根據(jù)上面講的,字符串2會變?yōu)閿?shù)字2,相等,返回true。
在看一個例子
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
這個呢,就是對象先調(diào)用valueOf()得到基本類型值3,然后再進(jìn)行比較得到true,第二個呢,得到了一個純凈的對象(沒有prototype),然后獲取不到valueOf()和toString(),直接報錯了。
那其他的情況呢
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
這個分析一下,規(guī)范中:
NaN不等于自身,+0和-0是相等的,對象是否相等是根據(jù)是否引用同一對象。
對象相等的已經(jīng)介紹完了,那么判斷不相等的呢?比如說(!=)和(!==)他們的區(qū)別呢
實(shí)際上,他們的語法判斷規(guī)則和相等的規(guī)則一樣,只不過最后多了一個置反的一個步驟。也就是!(a == b)或者是!(a === b),我感覺應(yīng)該很容易理解,就不舉例了。
那么最后就要講關(guān)系操作符了,也就是大于小于這些的。
那么我們先講兩個操作符中,有至少是一個數(shù)字的情況。請看下面的例子
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
上面這幾個例子,幾乎涵蓋了規(guī)范中至少有一個操作數(shù)是數(shù)字的比較的情況。
首先,也是如果有對象的話,會把對象轉(zhuǎn)為基本類型值,在進(jìn)行比較。
并且如果另一個操作數(shù)是字符串的話,會把字符串轉(zhuǎn)成數(shù)字。
還有就是數(shù)字一直小于正無窮,大于負(fù)無窮。
NaN無論怎么判斷都是false。
那么如果是字符串之間的比較呢,也就是倆操作數(shù)都是字符串的情況。
console.log("1003" > "2"); // false
嗯,很簡單是吧,如果倆都是字符串的話,實(shí)際上會按照字母順序去比,這樣去排出哪個值。
那么是怎么按照字母順序比的呢,字母順序又是通過什么方式取得的呢?請看例子:
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
這個例子,應(yīng)該就很容易理解了,實(shí)際上取的是字符串的charCodeAt(),實(shí)際上你依然可以理解為轉(zhuǎn)換成數(shù)字去比了,只不過字符串的比和含有數(shù)字的比是不一樣的,數(shù)字的比意味著他們整體數(shù)字的值的大小去比,而字符串是比從一開始的前綴挨個比每個字母的大小。
是不是依然比較好理解,那么在來一個例子。
var a = [ 42 ]; var b = "043"; console.log(a < b); // false console.log(Number(a) < Number(b)); // true
這個結(jié)合上面那個規(guī)則,自己分析下。
最后的最后,我們看一個你可能略感疑惑的例子:
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
這個例子,確實(shí)不太付合常識呀,但是呢,這確實(shí)是存在的,我給解釋一下。
首先呢,a < b和a > b,由于他們倆都是對象,所以轉(zhuǎn)換為基本類型值后為字符串“[object Object]”,所以返回false,而a == b呢,則是因為他倆并不是同一個對象的不同的引用,所以返回false。
最后倆呢,實(shí)際上大于等于或者小于等于可以理解為大于或者小于的值的反值,也就是: !(a <= b),所以前面為false,反一下為true
好啦,三個小章基本把強(qiáng)制類型轉(zhuǎn)換整個梳理了一遍,因為這一塊的細(xì)節(jié)太多,所以說呢,我反倒是建議讀到我這里的小伙伴,先把大體規(guī)則了解以后,特別細(xì)節(jié)的規(guī)則,用到的時候看看我的小散文,或者直接去看ecma262標(biāo)準(zhǔn)文檔也行,但是呢,強(qiáng)調(diào)一點(diǎn)就是,假如真的要用之前,還是建議自己吧代碼跑一下,這樣我的感觸就是要比只看效果好太多。
總之感謝大家收看我的小散文。
參考書籍《你不知道的Javascript中卷》
參考文檔:ECMAScript 5.1(ECMA-262)
https://www.ecma-internationa...
本文轉(zhuǎn)載自http://www.lht.ren/article/7/
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/100726.html
摘要:所以無論還是都會進(jìn)行類型轉(zhuǎn)換,唯一的區(qū)別,就是會置否而不會。這時候,肯定會有人問,假如說我有其他的數(shù)據(jù)類型呢,又不是數(shù)字又不是字符串,比如說數(shù)組啊,對象啊,布爾值啥的,那么如果是引用數(shù)據(jù)類型,則先轉(zhuǎn)為基本數(shù)據(jù)類型,再進(jìn)行比較。 上一章主要講了轉(zhuǎn)換到數(shù)字,字符串和布爾類型的一些知識點(diǎn),那么這一講接著上面的繼續(xù)講。 思考下面這個問題: console.log(+123); // 123 ...
摘要:轉(zhuǎn)換為字符串規(guī)則如下圖代碼大致就是普通其他基本類型轉(zhuǎn)為字符串的話,就直接轉(zhuǎn)為其值的字符串表達(dá)形式,如果是基本類型的封裝對象,會先拆封,然后再轉(zhuǎn)為字符串,如果是普通對象,則會調(diào)用其內(nèi)部的值,如果是極大數(shù)和級小數(shù),將會進(jìn)行一些轉(zhuǎn)化,具體規(guī) 轉(zhuǎn)換為字符串規(guī)則如下圖代碼: console.log(String(undefined)); // undefined console.log(Str...
摘要:前綴規(guī)范每個局部變量都需要有一個類型前綴,按照類型可以分為表示字符串。例如,表示以上未涉及到的其他對象,例如,表示全局變量,例如,是一種區(qū)分大小寫的語言。布爾值與字符串相加將布爾值強(qiáng)制轉(zhuǎn)換為字符串。 基本概念 javascript是一門解釋型的語言,瀏覽器充當(dāng)解釋器。js執(zhí)行時,在同一個作用域內(nèi)是先解釋再執(zhí)行。解釋的時候會編譯function和var這兩個關(guān)鍵詞定義的變量,編譯完成后從...
摘要:一返回值調(diào)用外部方法獲取的值需要對類型做判斷,因為我們對方法返回的值是有期望值類型,但是卻不能保證這個接口返回的值一直是同一個類型。 19年目標(biāo):消滅英語!我新開了一個公眾號記錄一個程序員學(xué)英語的歷程 有提升英語訴求的小伙伴可以關(guān)注公眾號:csenglish 程序員學(xué)英語,每天花10分鐘交作業(yè),跟我一起學(xué)英語吧 javascript作為一門動態(tài)類型語言,具有很高的動態(tài)靈活性,當(dāng)定義函數(shù)...
摘要:實(shí)際上,我們通常認(rèn)為是自有類型的唯一成員。比較運(yùn)算符的操作數(shù)可能是任意類型。結(jié)果只有,例得到操作值等價的布爾值真值為,假值為等同于,經(jīng)常稱為強(qiáng)制轉(zhuǎn)換。結(jié)果返回布爾值的用法是中唯一一個不等于任何值的包括它自己。 說起 js 類型轉(zhuǎn)換,都是頭疼吧,暈暈的,但是不行啊,這東西很重要滴! 基礎(chǔ)知識 JavaScript的數(shù)據(jù)類型分為六種,分別為null, undefined, boolean,...
閱讀 1021·2021-10-27 14:15
閱讀 2775·2021-10-25 09:45
閱讀 1941·2021-09-02 09:45
閱讀 3367·2019-08-30 15:55
閱讀 1807·2019-08-29 16:05
閱讀 3203·2019-08-28 18:13
閱讀 3117·2019-08-26 13:58
閱讀 455·2019-08-26 12:01