成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

NaN你都未必懂,花五分鐘讓你懂得不能再懂

開發(fā) 前端
NaN全稱是Not-A-Number,不是一個數(shù)字。在 JavaScript 中,整數(shù)和浮點數(shù)都統(tǒng)稱為 Number 類型。

[[431097]]

NaN和Number.NaN

NaN全稱是Not-A-Number,不是一個數(shù)字。在 JavaScript 中,整數(shù)和浮點數(shù)都統(tǒng)稱為 Number 類型。

特點1 typeof是數(shù)字

口上說不是一個數(shù)字,typeof的值卻是number, 口是心非。

ES6之后,Number也多了一個靜態(tài)屬性NaN

  1. typeof NaN // number 
  2. typeof Number.NaN // number 

特點2 我不等于我自己

我否定我自己,也就這家了。硬要說,還有一個+0和 -0

  1. NaN == NaN  // false 
  2. Number.NaN == NaN // false 
  3. NaN === NaN // false 
  4. Number.NaN === NaN  // false 
  5.  
  6. +0 == -0 // true 
  7. Object.is(+0, -0) // fasle 

NaN的描述信息

其是一個值,新的ES標準中, 不可配置,不可枚舉。也就是說不可以被刪除delete,不可以被改寫, 也不可以改寫配置。

  1. delete NaN // false 
  2. NaN = 1 // 1 
  3. NaN == 1 // false 
  4.  
  5. delete Number.NaN // false 
  6. Number.NaN = 1 // 1 
  7. Number.NaN == 1 // false 

我們嘗試改寫:

使用Reflect.defineProperty 而不使用Object.defineProperty,因為前者能準確告訴你是否成功,而后者返回的被定義的對象。

  1. const success =Reflect.getOwnPropertyDescriptor(window, 'NaN'), { 
  2.     writable: true
  3.     configurable: true
  4. }) 
  5. console.log(success) // false 
  6. Reflect.getOwnPropertyDescriptor(window, 'NaN'
  7. // {value: NaN, writable: false, enumerable: false, configurable: false

結(jié)果是無法改寫,所以不要打他的小心思。

常見的場景

計算, 類型轉(zhuǎn)換是典型的場景

  1. let print = console.log; 
  2. // parseInt  
  3. print(isNaN(parseInt("zz123"))) // true 
  4.  
  5. // parseFloat  
  6. print(isNaN(parseFloat("zz123"))) // true 
  7.  
  8. // 直接Number初始化 
  9. print(isNaN(Number("zz123"))) // true 
  10.  
  11. // 數(shù)字運算 
  12. print(isNaN(0 / 0 ))  // true 
  13. print(isNaN( 1 * "zz123" )) // true 
  14. print(Math.sqrt(-1)) // true 

isNaN

isNaN() 是一個全局方法。

其本質(zhì)是檢查 toNumber 返回值, 如果是NaN,就返回 true,反之返回 false 。

可以簡化為語義:

  1. Number.isNaN =  function (val){ 
  2.    return Object.is(Number(val), NaN);  

toNumber 方法, 大致的邏輯如下:

le 15: ToNumber Conversions

Argument Type Result
Undefined Return NaN.
Null Return +0𝔽.
Boolean If argument is true, return 1𝔽. If argument is false, return +0𝔽.
Number Return argument (no conversion).
String Return ! StringToNumber(argument).
Symbol Throw a TypeError exception.
BigInt Throw a TypeError exception.

關(guān)于對象的轉(zhuǎn)換是:

1. Let primValue be ? ToPrimitive(argument, number).

2. Return ? ToNumber(primValue).

簡單翻譯就是先獲取原始類型的值,再轉(zhuǎn)為Number。

取原值,也會根據(jù)條件執(zhí)行不同的方法。

最優(yōu)先調(diào)用 Symbol.toPrimitive, 如果存在

根據(jù)條件決定是先調(diào)用 valueOf 還是toString

對象這里就比較有意思了, 看下面的例子, valueOf的返回,可以直接影響isNaN的值。

  1. let print = console.log; 
  2. var person = { 
  3.     age: 10, 
  4.     name"tom"
  5.     valueOf(){ 
  6.         return this.name  
  7.     } 
  8. print(isNaN(person))  // true 
  9.  
  10.  
  11. let print = console.log; 
  12. var person = { 
  13.     age: 10, 
  14.     name"tom"
  15.     valueOf(){ 
  16.         return this.age  
  17.     } 
  18. print(isNaN(person))  // false 

常規(guī)例子:

  1. let print = console.log; 
  2. print(isNaN("123")) //false 
  3. print(isNaN('zz123')) //true 
  4. print(isNaN(NaN)) //true 

isNaN是可以被刪除的,但是不可被枚舉:

  1. delete isNaN // true 
  2. typeof // undefined 
  3.  
  4. isNaN = 1  // 1 
  5. isNaN == 1  //true 

屬性描述信息:

Number.isNaN

判斷一個值是否是數(shù)字,并且值等于NaN.

ES標準的描述:

  1. If Type(number) is not Number, return false
  2. If number is NaN, return true
  3. Otherwise, return false

所有可以語義化為:

  1. Number.isNaN = function(val){ 
  2.    if(typeof val !== "number"){ 
  3.        return false 
  4.    } 
  5.    return Object.is(val, NaN); 

demo:

  1. let print = console.log; 
  2.  
  3. print(Number.isNaN(NaN))  // true 
  4. print(Number.isNaN("123")) //false 

isNaN和Number.isNaN的區(qū)別

Number.isNaN是嚴格判斷, 必須嚴格等于NaN。是不是NaN這個值

isNaN是通過內(nèi)部的 toNumber 轉(zhuǎn)換結(jié)果來判定的。Number轉(zhuǎn)換的返回值是不是NaN

Number.isNaN是ES6的語法,固然存在一定的兼容性問題。

Object.is

ES6標準新增方法,用于判斷兩個值是否屬于同一個值,其能準確的判斷NaN。

  1. let print = console.log; 
  2.  
  3. print(Object.is(NaN, NaN)); // true 
  4. print(Object.is("123", NaN)) // false 

嚴格判斷NaN匯總

四種,2種ES6, 2種ES5。

  1. Number.isNaN(NaN) // true 
  2. Number.isNaN(1) // false 

Object.is (ES6)

  1. function isNaNVal(val){ 
  2.     return Object.is(val, NaN); 
  3. isNaNVal(NaN) // true 
  4. isNaNVal(1) // false 

自身比較 (ES5)

最為簡單的一種方式。

  1. function isNaNVal(val){ 
  2.     return val !== val; 
  3. isNaNVal(NaN) // true 
  4. isNaNVal(1) // false 

typeof + NaN (ES5)

這是MDN推薦的墊片,有些兼容低版本的庫就是這么實現(xiàn)的, 也是ES標準的精準表達

  1. function isNaNVal(val){ 
  2.     return typeof val === 'number' && isNaN(val) 

綜合的墊片

  1. if(!("isNaN" in Number)) { 
  2.     Number.isNaN = function (val) { 
  3.       return typeof val === 'number' && isNaN(val) 
  4.     } 

深究數(shù)組的indexOf與includes

三心醬在50個JS高級知識點有提到 includes能識別 NaN, 我們繼續(xù)來一看究竟。

  1. var arr=[NaN]; 
  2. arr.indexOf(NaN) // -1 
  3. arr.includes(NaN) // true 

includes

我們深入規(guī)范看一看:

ES標準的Array.prototype.includes 比較值相等調(diào)用的是內(nèi)部的 SameValueZero ( x, y )方法,其會檢查值第一值是不是數(shù)字,如果是數(shù)字,調(diào)用的是 Number::sameValueZero(x, y), 其具體比較步驟:

  1. 1. If x is NaN and y is NaN, return true
  2.  
  3. 2. If x is +0?? and y is -0??, return true
  4.  
  5. 3. If x is -0?? and y is +0??, return true
  6.  
  7. 4. If x is the same Number value as y, return true
  8.  
  9. 5. Return false

其先對NaN進行了比較,所以能檢查NaN, 這里還有一個額外信息,比較的時候+0和-0是相等的, 要區(qū)分+0和-0還得用Object.is

indexOf

ES標準中 Array.prototype.indexOf 值比較調(diào)用的是IsStrictlyEqual(searchElement, elementK), 其如果檢查到第一個值為數(shù)字,調(diào)用的 Number::equal(x, y).

其比對邏輯

  1. 1. If x is NaN, return false. 2. If y is NaN, return false. 3. If x is the same Number value as y, return true. 4. If x is +0𝔽 and y is -0𝔽, return true. 5. If x is -0𝔽 and y is +0𝔽, return true
  2. 6. Return false

可以看到,任何一個為NaN,就直接返回false,必然不能嚴格的檢查NaN.

Number::sameValueZero 和 Number::sameValue

區(qū)別

在上個章節(jié)我們提到了,Array.prototype.includes值的比較實用的是 Number::sameValueZero , 突出了Zero, Zero是什么,是0啊,也就是說對0進行了特殊的處理。

對應(yīng)的還要一個 Number::sameValue 方法, 一起看看:

可以看出Number::sameValueZero 不區(qū)分+0 -0, Number::sameValue 則區(qū)分。

  1. Object.is(+0, -0) // false, 區(qū)分+0,-0 
  2. [-0].includes(+0) // true,不區(qū)分+0,-0 

BigInt::sameValue和 BigInt:samgeValueZero

圖片可以看出,除了Number有, BigInt也有相似的比較。

這兩個方法的主要應(yīng)用場景也就是 Object.is 和 Array.prototype.includes。

再猜猜下面的結(jié)果:

  1. Object.is(BigInt(+0),BigInt(-0)) 
  2. Object.is(-0n,0n) 
  3. Object.is(-0,0) 
  4. [BigInt(+0)].includes(BigInt(-0)) 

3

2

1

結(jié)果,不如你所愿:

  1. Object.is(BigInt(+0),BigInt(-0))   // true 
  2. Object.is(-0n,0n) // true 
  3. Object.is(-0,0) // false 
  4. [BigInt(+0)].includes(BigInt(-0))  // false 

哈哈,更多細節(jié) BigInt::equal ( x, y ):

核心解釋:

BigInt::sameValue ( x, y ) 調(diào)用 BigInt::equal ( x, y )

  1. BigInt::equal ( x, y ) 
  2. 1. If ℝ(x) = ℝ(y), return true; otherwise return false

而R(x)是啥玩意

  1. 從 Number 或 BigInt x 到數(shù)學(xué)值的轉(zhuǎn)換表示為“ x 的數(shù)學(xué)值”或 R(x)。+ 0F 和-0F的數(shù)學(xué)值為0 

簡單的結(jié)論:

  • Number區(qū)分+0,- 0
  • BitInt不區(qū)分

BigInt::sameValue和 BigInt:samgeValueZero有什么區(qū)別呢?

用一張圖,更好解釋:

沒有區(qū)別,更合理的解釋是什么呢??

小結(jié)

indexOf是ES5甚至更早的產(chǎn)物,includes是ES6的產(chǎn)物。高級產(chǎn)物向著更合理化的方向發(fā)展,合情合理。

至于為什么不升級indexOf呢,歷史包袱吧,以前的代碼總不能讓其產(chǎn)生意外效果吧。

 

責任編輯:武曉燕 來源: 云的程序世界
相關(guān)推薦

2017-07-12 09:54:33

深度學(xué)習(xí)AI 人工智能

2009-11-05 10:56:31

WCF通訊

2021-03-04 09:26:57

微服務(wù)架構(gòu)數(shù)據(jù)

2024-04-28 12:55:46

redis頻道機制

2021-11-07 23:46:32

MySQLSQL索引

2020-12-08 10:02:25

RESTfulAPI開發(fā)

2009-11-06 16:05:37

WCF回調(diào)契約

2021-11-11 15:03:35

MySQLSQL索引

2020-11-09 09:59:50

Ajax技術(shù)

2017-12-19 10:10:47

2017-06-07 18:40:33

PromiseJavascript前端

2022-03-08 08:39:22

gRPC協(xié)議云原生

2009-10-29 11:39:52

ADO.NET連接池

2024-02-21 21:19:18

切片Python語言

2024-08-02 08:31:08

2023-07-15 18:26:51

LinuxABI

2021-08-14 06:46:02

Excel技巧Word

2015-12-03 14:10:26

systemd容器Linux

2020-11-06 08:54:43

Vue 3.0函數(shù)代碼

2015-11-12 10:32:40

GitHub控制系統(tǒng)分布式
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久草视频在线播放 | 一区二区三区亚洲精品国 | 在线播放第一页 | 欧美一级在线观看 | 久久久91| 婷婷综合| 欧美性影院 | 夜夜爽99久久国产综合精品女不卡 | 欧美日韩视频 | 日韩精品久久久久 | 一级黄色片在线免费观看 | 国产一区二区三区四区五区加勒比 | 国产精品一区二区不卡 | 日韩一级电影免费观看 | 国产乡下妇女做爰 | 一区二区三区在线播放 | 国产精品自产拍在线观看蜜 | 久在线 | k8久久久一区二区三区 | 国产精品高潮呻吟 | 国产精品美女视频 | 91成人午夜性a一级毛片 | 久久久久久久久国产成人免费 | 成人久久网 | 一区二区三区中文字幕 | 国产精品久久久乱弄 | 99精品久久久久久久 | 正在播放国产精品 | 久久国产视频播放 | 欧美激情a∨在线视频播放 成人免费共享视频 | h视频免费在线观看 | 久久久久综合 | 日本欧美黄色片 | 天天干夜夜 | 久草中文在线观看 | 在线播放一区二区三区 | 日韩欧美综合 | 好姑娘高清在线观看电影 | 91在线一区 | 美女网站视频免费黄 | 亚洲自拍一区在线观看 |