JS - NaN

一、特性

ES6之后,Number也多了一个静态属性NaN

1. typeof
typeof NaN // number
typeof Number.NaN // number
2. 不等于自身
NaN === NaN // false
Number.NaN === NaN  // false
3. 不能修改自身属性

新的ES标准中, 不可配置,不可枚举。也就是说不可以被删除delete,不可以被改写, 也不可以改写配置。

delete NaN // false
NaN = 1 // 1
NaN == 1 // false

delete Number.NaN // false
Number.NaN = 1 // 1
Number.NaN == 1 // false
Reflect.getOwnPropertyDescriptor(window, 'NaN')
// {value: NaN, writable: false, enumerable: false, configurable: false}

二、isNaN 和 Number.isNaN

1. isNaN

isNaN() 是一个全局方法。
其本质是检查 toNumber 返回值, 如果是NaN,就返回 true,反之返回 false 。
toNumber 方法, 大致的逻辑如下:

Argument TypeResult
UndefinedReturn NaN.
NullReturn +0𝔽.
BooleanIf argument is true, return 1𝔽. If argument is false, return +0𝔽.
NumberReturn argument (no conversion).
StringReturn ! StringToNumber(argument).
SymbolThrow a TypeError exception.
BigIntThrow a TypeError exception

简单来说就是,

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

判断一个值是否是数字,并且值等于NaN

ES标准的描述:

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

可以语义化为

Number.isNaN = function(val){
   if(typeof val !== "number"){
       return false
   }
   return Object.is(val, NaN);
}
3. isNaN和Number.isNaN的区别
  1. Number.isNaN是严格判断, 必须严格等于NaN。是不是NaN这个值
  2. isNaN是通过内部的 toNumber 转换结果来判定的。Number转换的返回值是不是NaN
  3. Number.isNaN是ES6的语法,固然存在一定的兼容性问题。

三、严格判断NaN

1. Number.isNaN (ES6)
Number.isNaN(NaN) // true
Number.isNaN(1) // false
2. Object.is (ES6)
Object.is(NaN, NaN);  // true
Object.is(1, NaN); // false
Object.is("123", NaN) // false
3. 自身比较 (ES5)
function isNaNVal(val){
    return val !== val;
}
isNaNVal(NaN) // true
isNaNVal(1) // false
4. typeof + NaN (ES5)

这是MDN推荐的垫片,有些兼容低版本的库就是这么实现的, 也是ES标准的精准表达

function isNaNVal(val){
    return typeof val === 'number' && isNaN(val)
}

四、indexOf 和 includes 识别NaN

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

ES标准的Array.prototype.includes 比较值相等调用的是内部的 SameValueZero ( x, y )方法,其会检查值第一值是不是数字,如果是数字,调用的是 Number::sameValueZero(x, y), 其具体比较步骤:

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

其先对NaN进行了比较,所以能检查NaN, 这里还有一个额外信息,比较的时候+0和-0是相等的, 要区分+0和-0还得用Object.is

2. indexOf

ES标准中 Array.prototype.indexOf 值比较调用的是IsStrictlyEqual(searchElement, elementK), 其如果检查到第一个值为数字,调用的 Number::equal(x, y), 其具体比较步骤:

  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.
  6. Return false.

可以看到,任何一个为NaN,就直接返回false,必然不能严格的检查NaN.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值