<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在 JavaScript 中如何判斷兩個值相等,這個問題看起來非常簡單,但並非如此,在 JavaScript 中存在 4 種不同的相等邏輯,如果你不知道他們的區別,或者認為判斷相等非常簡單,那麼本文非常適合你閱讀。
ECMAScript 是 JavaScript 的語言規範,在ECMAScript 規範中存在四種相等演演算法,如下圖所示:
上圖中四種演演算法對應的中文名字如下,大部分前端應該熟悉嚴格相等和非嚴格相等,但對於同值零和同值卻不熟悉,下面我們分別介紹這四種演演算法。
非嚴格相等使用兩個等號,也就是我們熟悉的雙等,非嚴格相等表示語意相等,不要求型別一樣,非嚴格相等在比較前會先將比較引數型別轉換為一致,再進行比較,程式碼範例如下:
1 == 1; // true 1 == '1'; // true 型別不同,不影響比較結果
非嚴格相等有非常複雜的轉換規則,非常難以記憶,社群中有人將上面的規則總結成了圖片,一圖勝千言,如下圖所示:
為了方便記住非嚴格相等的的轉換邏輯,作者將非物件值,可以總結為如下三條規則:
如果值為物件,會使用內部的 ToPrimitive 轉換,可以通過自定義 Symbol.toPrimitive 改變返回值,需要注意的是在相等的判斷中 Symbol.toPrimitive 接受的 hint 引數都是 default。
const obj = { [Symbol.toPrimitive](hint) { console.log(hint); if (hint == 'number') { return 1; } if (hint == 'string') { return 'yan'; } return true; }, }; console.log(obj == 1); // obj 返回 true console.log(obj == '1'); // obj 返回 true console.log(obj == true); // obj 返回 true
非嚴格相等並非帶來了很多便利,通過隱式的自動轉換,簡化了部分場景的工作,比如 Number 和 String 的自動轉換,簡化了前端從表單,url 引數中獲取值的比較問題,但自動轉換帶來的問題比便利還多。
隱式轉換的規則,大部分情況下難以駕馭,現在主流的觀點已經不建議使用,作者建議只在判斷 undefined 和 null 的場景下可以使用非嚴格相等。
嚴格相等是另一種比較演演算法,其和非嚴格想等的區別是不會進行型別轉換,型別不一致時直接返回 false,嚴格相等對應===操作符,因為使用三個等號,也被稱作三等或者全等,嚴格相等範例如下:
1 === 1; // true 1 === '1'; // false 型別不同,影響比較結果
不同型別值判斷規則如下,和前面的非嚴格相等對比,嚴格相等更符合直覺。
嚴格相等解決了非嚴格相等中隱式轉換帶來的問題,但也丟失了隱式轉換帶來的便利,對於型別可能不一致的情況下,比如從表單中獲取的值都是字串,保險的做法是,在比較前手動型別轉換,程式碼範例如下:
1 === Number('1'); // true 手動型別轉換,型別防禦
嚴格相等幾乎總是正確的,但也有例外情況,比如 NaN 和正負 0 的問題。
Number 型別有個特殊的值 NaN,用來表示計算錯誤的情概況,比較常見是非 Number 型別和 Number 型別計算時,會得到 NaN 值,程式碼範例如下所示,這是從表單和介面請求獲取資料時很容易出現的問題。
const a = 0 / 0; // NaN const b = 'a' / 1; const c = undefined + 1; // NaN
在嚴格相等中,NaN 是不等於自己的,NaN 是(x !== x) 成立的唯一情況,在某些場景下其實是希望能夠判斷 NaN 的,可以使用 isNaN 進行判斷,ECMAScript 2015 引入了新的 Number.isNaN,和 isNaN 的區別是不會對傳入的引數做型別轉換,建議使用語意更清晰的 Number.isNaN,但是要注意相容性問題,判斷 NaN 程式碼範例如下:
NaN === NaN; // false isNaN(NaN); // true Number.isNaN(NaN); // true isNaN('aaa'); // true 自動轉換型別 'aaa'轉換為Number為NaN Number.isNaN('aaa'); // false 不進行轉換,型別不為Number,直接返回false
嚴格相等另一個例外情況是,無法區分+0 和-0,程式碼範例如下,在一些數學計算場景中是要區分語意的。
+0 === -0; // true
JavaScript 中很多系統函數都使用嚴格相等,比如陣列的 indexOf,lastIndexOf 和 switch-case 等,需要注意,這些對於 NaN 無法返回正確結果,程式碼範例如下:
[NaN].indexOf(NaN); // -1 陣列中其實存在NaN [NaN].lastIndexOf(NaN); // -1
同值零是另一種相等演演算法,名字來源於規範的直譯,規範中叫做 SameValueZero,同值零和嚴格相等功能一樣,除了處理 NaN 的方式,同值零認為 NaN 和 NaN 相等,這在判斷 NaN 是否在集合中的語意下是非常合理的。
ECMAScript 2016 引入的 includes 使用此演演算法,此外 Map 的鍵去重和 Set 的值去重,使用此演演算法,程式碼範例如下:
[NaN].incdudes(NaN); // true 注意和indexOf的區別,incdudes的語意更合理 new Set([NaN, NaN]); // [NaN] set中只會有個一個NaN,如果 NaN !== NaN的話,應該是[NaN, NaN] new Map([ [NaN, 1], [NaN, 2], ]); // {NaN => 2} 如果 NaN !== NaN的話,應該是 {NaN => 1, NaN => 2}
同值是最後一種相等演演算法,其和同值零類似,但認為 +0 不等於 -0,ECMAScript 2015 帶來的 Object.is 使用同值演演算法,程式碼範例如下:
Object.is(NaN, NaN); // true Object.is(+0, -0); // false
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45