欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript判斷兩個值相等的方法詳解

 更新時間:2022年07月11日 08:52:56   作者:顏海鏡  
在?JavaScript?中如何判斷兩個值相等,這個問題看起來非常簡單,但并非如此,在?JavaScript?中存在?4?種不同的相等邏輯,如果你不知道他們的區(qū)別,或者認為判斷相等非常簡單,本文就來為大家詳細講講

前言

在 JavaScript 中如何判斷兩個值相等,這個問題看起來非常簡單,但并非如此,在 JavaScript 中存在 4 種不同的相等邏輯,如果你不知道他們的區(qū)別,或者認為判斷相等非常簡單,那么本文非常適合你閱讀。

ECMAScript 是 JavaScript 的語言規(guī)范,在ECMAScript 規(guī)范中存在四種相等算法,如下圖所示:

上圖中四種算法對應的中文名字如下,大部分前端應該熟悉嚴格相等和非嚴格相等,但對于同值零和同值卻不熟悉,下面我們分別介紹這四種算法。

  • 同值
  • 同值零
  • 非嚴格相等
  • 嚴格相等

非嚴格相等

非嚴格相等使用兩個等號,也就是我們熟悉的雙等,非嚴格相等表示語義相等,不要求類型一樣,非嚴格相等在比較前會先將比較參數(shù)類型轉換為一致,再進行比較,代碼示例如下:

1 == 1; // true
1 == '1'; // true 類型不同,不影響比較結果

非嚴格相等有非常復雜的轉換規(guī)則,非常難以記憶,社區(qū)中有人將上面的規(guī)則總結成了圖片,一圖勝千言,如下圖所示:

為了方便記住非嚴格相等的的轉換邏輯,作者將非對象值,可以總結為如下三條規(guī)則:

  • Undefined 只和 Null 相等
  • 和 Number 比較時,另一個值會自動轉換為 Number
  • 和 Boolean 比較時,另一個值會轉換為 Number

如果值為對象,會使用內部的 ToPrimitive 轉換,可以通過自定義 Symbol.toPrimitive 改變返回值,需要注意的是在相等的判斷中 Symbol.toPrimitive 接受的 hint 參數(shù)都是 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 參數(shù)中獲取值的比較問題,但自動轉換帶來的問題比便利還多。

隱式轉換的規(guī)則,大部分情況下難以駕馭,現(xiàn)在主流的觀點已經不建議使用,作者建議只在判斷 undefined 和 null 的場景下可以使用非嚴格相等。

嚴格相等

嚴格相等是另一種比較算法,其和非嚴格想等的區(qū)別是不會進行類型轉換,類型不一致時直接返回 false,嚴格相等對應===操作符,因為使用三個等號,也被稱作三等或者全等,嚴格相等示例如下:

1 === 1; // true
1 === '1'; // false 類型不同,影響比較結果

不同類型值判斷規(guī)則如下,和前面的非嚴格相等對比,嚴格相等更符合直覺。

嚴格相等解決了非嚴格相等中隱式轉換帶來的問題,但也丟失了隱式轉換帶來的便利,對于類型可能不一致的情況下,比如從表單中獲取的值都是字符串,保險的做法是,在比較前手動類型轉換,代碼示例如下:

1 === Number('1'); // true 手動類型轉換,類型防御

嚴格相等幾乎總是正確的,但也有例外情況,比如 NaN 和正負 0 的問題。

Number 類型有個特殊的值 NaN,用來表示計算錯誤的情概況,比較常見是非 Number 類型和 Number 類型計算時,會得到 NaN 值,代碼示例如下所示,這是從表單和接口請求獲取數(shù)據(jù)時很容易出現(xiàn)的問題。

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 的區(qū)別是不會對傳入的參數(shù)做類型轉換,建議使用語義更清晰的 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

嚴格相等另一個例外情況是,無法區(qū)分+0 和-0,代碼示例如下,在一些數(shù)學計算場景中是要區(qū)分語義的。

+0 === -0; // true

JavaScript 中很多系統(tǒng)函數(shù)都使用嚴格相等,比如數(shù)組的 indexOf,lastIndexOf 和 switch-case 等,需要注意,這些對于 NaN 無法返回正確結果,代碼示例如下:

[NaN].indexOf(NaN); // -1 數(shù)組中其實存在NaN
[NaN].lastIndexOf(NaN); // -1

同值零

同值零是另一種相等算法,名字來源于規(guī)范的直譯,規(guī)范中叫做 SameValueZero,同值零和嚴格相等功能一樣,除了處理 NaN 的方式,同值零認為 NaN 和 NaN 相等,這在判斷 NaN 是否在集合中的語義下是非常合理的。

ECMAScript 2016 引入的 includes 使用此算法,此外 Map 的鍵去重和 Set 的值去重,使用此算法,代碼示例如下:

[NaN].incdudes(NaN); // true 注意和indexOf的區(qū)別,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 ?? 注意這里

同值算法的使用場景是,確定兩個值是否在任何情況下功能上是相同的,比較不常用,defineProperty 使用此算法確認鍵是否存在,例如,將存在的只讀屬性值-0 修改為+0 時會報錯,如果設置為同樣的-0 將執(zhí)行正常,代碼示例如下:

function test() {
  'use strict'; // 需要開啟嚴格模式
  var a = {};

  Object.defineProperty(a, 'a1', {
    value: -0,
    writable: false,
    configurable: false,
    enumerable: false,
  });

  Object.defineProperty(a, 'a1', {
    value: -0,
  }); // 正常執(zhí)行

  Object.defineProperty(a, 'a1', {
    value: 0,
  }); // Uncaught TypeError: Cannot redefine property: a1
}
test();

對于數(shù)組判斷是否存在的場景,如果想?yún)^(qū)分+0 和-0,可以使用 ECMAScript 2015 引入的 find 方法,自行控制判斷邏輯,代碼示例如下:

[0].includes(-0); // 不能區(qū)分-0
[0].find((val) => Object.is(val, -0)); // 能區(qū)分+0和-0

總結

最后來對比下四種算法的區(qū)別,區(qū)別如下表所示:

 隱式轉換NaN 和 NaN+0 和 -0
非嚴格相等(==)falsetrue
嚴格相等(===)falsetrue
同值零(includes 等)truetrue
同值(Object.is)truefalse

到此這篇關于JavaScript判斷兩個值相等的方法詳解的文章就介紹到這了,更多相關JavaScript判斷值相等內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • JS中的模糊查詢功能

    JS中的模糊查詢功能

    這篇文章主要介紹了JS中的模糊查詢功能,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • JavaScript對象字面量和構造函數(shù)原理與用法詳解

    JavaScript對象字面量和構造函數(shù)原理與用法詳解

    這篇文章主要介紹了JavaScript對象字面量和構造函數(shù),結合實例形式分析了JavaScript對象字面量和構造函數(shù)相關概念、原理、用法及操作注意事項,需要的朋友可以參考下
    2020-04-04
  • php中給js數(shù)組賦值方法

    php中給js數(shù)組賦值方法

    PHP函數(shù)庫提供了編/解碼JSON的函數(shù):json_encode()和json_decode(),可以比較方便的傳遞數(shù)組或對象給javascript
    2014-03-03
  • TypeScript中類的基礎概念和使用詳解

    TypeScript中類的基礎概念和使用詳解

    這篇文章主要為大家詳細介紹了TypeScript?中類的概念和用法,文中的示例代碼講解詳細,希望能幫助大家更好地理解和運用?TypeScript?中的類
    2023-06-06
  • 提高網站性能之 如何對待JavaScript

    提高網站性能之 如何對待JavaScript

    在一個頁面中,每一個外部JavaScript 及CSS文件都會導致一個額外的HTTP請求。所以,如何合理的合并JavaScript 文件及CSS文件也是前端工程師應該考慮的。
    2009-10-10
  • js前端如何寫一個精確的倒計時代碼

    js前端如何寫一個精確的倒計時代碼

    關于寫倒計時大家可能都都比較熟悉,使用 setTimeout 或 setInterval 就可以搞定。幾秒鐘或者幾分鐘的倒計時這樣寫沒有問題,但是如果是長時間的倒計時,這樣寫就會不準確
    2019-10-10
  • 微信小程序實現(xiàn)列表分頁功能

    微信小程序實現(xiàn)列表分頁功能

    這篇文章主要為大家詳細介紹了微信小程序實現(xiàn)列表分頁功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • JavaScript array常用方法代碼實例詳解

    JavaScript array常用方法代碼實例詳解

    這篇文章主要介紹了JavaScript array常用方法代碼實例詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • js計算系統(tǒng)當前日期是星期幾的方法

    js計算系統(tǒng)當前日期是星期幾的方法

    這篇文章主要為大家詳細介紹了js計算系統(tǒng)當前日期是星期幾4種方法,需要的朋友可以參考下
    2016-07-07
  • Javascript實用方法之json合并的場景分析

    Javascript實用方法之json合并的場景分析

    這篇文章主要介紹了Javascript實用方法之json合并,jQuery 的“extend()”方法有兩個原型:合并的方法,分別是淺合并和深度合并,本文通過代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-09-09

最新評論