This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
NaN and Number. NaN
NaN is A not-a-number, Not A Number. In JavaScript, both integers and floating point numbers are collectively called Number types.
Feature 1 Typeof is a number
Typeof (” number “, “number”); After ES6, Number also has a static NaN attribute
typeof NaN // number
typeof Number.NaN // number
Copy the code
Trait 2 I am not equal to myself
I deny myself, and that’s it. And, of course, there’s a plus 0 and a minus 0
NaN= =NaN // false
Number.NaN == NaN // false
NaN= = =NaN // false
Number.NaN === NaN // false
+0= = -0 // true
Object.is(+0, -0) // fasle
Copy the code
Description of NaN
It is a value that, in the new ES standard, is not configurable or enumerable. Delete cannot be deleted, cannot be overwritten, and cannot be overwritten.
delete NaN // false
NaN = 1 / / 1
NaN= =1 // false
delete Number.NaN // false
Number.NaN = 1 / / 1
Number.NaN == 1 // false
Copy the code
We tried rewriting: use reflect.defineProperty instead of Object.defineProperty, because the former will tell you exactly if you succeeded, while the latter returns the defined Object.
const success =Reflect.getOwnPropertyDescriptor(window.'NaN'), {
writable: true.configurable: true,})console.log(success) // false
Reflect.getOwnPropertyDescriptor(window.'NaN')
// {value: NaN, writable: false, enumerable: false, configurable: false}
Copy the code
It turns out it can’t be rewritten, so don’t beat him up.
Common Scenarios
Computation, casting is a typical scenario
let print = console.log;
// parseInt
print(isNaN(parseInt("zz123"))) // true
// parseFloat
print(isNaN(parseFloat("zz123"))) // true
// Initialize Number directly
print(isNaN(Number("zz123"))) // true
// Number manipulation
print(isNaN(0 / 0 )) // true
print(isNaN( 1 * "zz123" )) // true
print(Math.sqrt(-1)) // true
Copy the code
isNaN
IsNaN () is a global method. The essence of this is to check the value returned by toNumber, true if it is NaN and false if it is not.
Can be simplified to semantics:
Number.isNaN = function (val){
return Object.is(Number(val), NaN);
}
Copy the code
ToNumber method, the general logic is as follows:
le 15: ToNumber Conversions
Argument Type | Result |
---|---|
Undefined | Return NaN. |
Null | Return + 0 𝔽. |
Boolean | If argument Is true, return 1𝔽argument Is false, return + 0 𝔽. |
Number | Return argument (no conversion). |
String | Return ! StringToNumber(argument ). |
Symbol | Throw a TypeError exception. |
BigInt | Throw a TypeError exception. |
1. Let primValue be? ToPrimitive(argument, number). 2. Return ? ToNumber(primValue).
The simple translation is to get the value of the original type and convert it to Number.
Taking the original value, different methods are executed depending on the condition.
- Top priority call
Symbol.toPrimitive
, if there is - Whether to call valueOf or toString first depends on the condition
Object is a bit more interesting. In the following example, the return from valueOf can directly affect the valueOf isNaN.
let print = console.log;
var person = {
age: 10.name: "tom".valueOf(){
return this.name
}
}
print(isNaN(person)) // true
let print = console.log;
var person = {
age: 10.name: "tom".valueOf(){
return this.age
}
}
print(isNaN(person)) // false
Copy the code
General examples:
let print = console.log;
print(isNaN("123")) //false
print(isNaN('zz123')) //true
print(isNaN(NaN)) //true
Copy the code
IsNaN can be deleted, but cannot be enumerated:
delete isNaN // true
typeof // undefined
isNaN = 1 / / 1
isNaN= =1 //true
Copy the code
Attribute Description:
Number.isNaN
Determines whether a value is a number and is equal to NaN.
Description of ES standard:
- If Type(
number
) is not Number, return false.- If
number
is NaN, return true.- Otherwise, return false.
All can be semantically translated as:
Number.isNaN = function(val){
if(typeofval ! = ="number") {return false
}
return Object.is(val, NaN);
}
Copy the code
demo:
let print = console.log;
print(Number.isNaN(NaN)) // false
print(Number.isNaN("123")) //true
Copy the code
IsNaN and number. isNaN
Number. IsNaN is a strict judgment and must be strictly equal to NaN. Is the value NaN
IsNaN is determined by internal toNumber transformation results. The return value of the Number conversion is NaN
Number. IsNaN is an ES6 syntax with some compatibility issues.
Object.is
ES6 standard added a method to determine whether two values belong to the same value, which can accurately determine NaN.
let print = console.log;
print(Object.is(NaN.NaN)); // true
print(Object.is("123".NaN)) // false
Copy the code
Strictly judge NaN summaries
Four, two ES6s, two ES5s.
Number.isNaN (ES6)
Number.isNaN(NaN) // true
Number.isNaN(1) // false
Copy the code
Object.is (ES6)
function isNaNVal(val){
return Object.is(val, NaN);
}
isNaNVal(NaN) // true
isNaNVal(1) // false
Copy the code
Self comparison (ES5)
The simplest way to do it.
function isNaNVal(val){
returnval ! == val; } isNaNVal(NaN) // true
isNaNVal(1) // false
Copy the code
typeof + NaN (ES5)
This is the MDN recommended gasket, some compatible with lower versions of the library is implemented in this way, is an accurate expression of the ES standard
function isNaNVal(val){
return typeof val === 'number' && isNaN(val)
}
Copy the code
Integrated gasket
if(! ("isNaN" in Number)) {
Number.isNaN = function (val) {
return typeof val === 'number' && isNaN(val)
}
}
Copy the code
Dig into the array indexOf and includes
NaN can be identified in this section.
var arr=[NaN];
arr.indexOf(NaN) // -1
arr.includes(NaN) // true
Copy the code
includes
Let’s take a closer look at the specification:
The ES standard array.prototype. includes method calls the internal SameValueZero (x, y) method, which checks if the first value is a number. Call Number::sameValueZero(x, y)
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.
It compares nans first, so it can check nans. Here’s an additional piece of information: +0 and -0 are equal when comparing, and you have to use object.is to distinguish +0 from -0
indexOf
IndexOf (searchElement, elementK); Number::equal(x, y);
Its comparative logic
1. If x is NaN, return false. 2. If y is NaN, return false. 3. If x is the same Number value as y, If x is +0𝔽 and y is-0 𝔽, return true. 5. If x is-0 𝔽 and y is +0𝔽, return true. 6.
As you can see, if any NaN is returned, false will not be strictly checked for NaN.
Number::sameValueZero 和 Number::sameValue
The difference between
Array.prototype.includes Number::sameValueZero.
SameValue = sameValue = sameValue = sameValue = sameValue = sameValue
It can be seen thatNumber::sameValueZeroDoes not distinguish between+0 -0
.Number::sameValueThe distinction.
Object.is(+0, -0) // false to distinguish +0 from -0
[-0].includes(+0) // true, regardless of +0,-0
Copy the code
BigInt: : sameValue and BigInt: samgeValueZero
In addition to Number, BigInt has similar comparisons.
The main application scenarios of these two methods are Object.is and array.prototype. includes.
And guess the following:
Object.is(BigInt(+0),BigInt(-0))
Object.is(-0n.0n)
Object.is(-0.0)
[BigInt(+0)].includes(BigInt(-0))
Copy the code
3 2 1 Result, not as you expected:
Object.is(BigInt(+0),BigInt(-0)) // true
Object.is(-0n.0n) // true
Object.is(-0.0) // false
[BigInt(+0)].includes(BigInt(-0)) // false
Copy the code
BigInt::equal (x, y) :
Call BigInt::sameValue (x, y) to equal (x, y)
BigInt::equal (x, y) 1. If ℝ(x) = ℝ(y), return true; otherwise return false.
And R of x is something
The conversion from Number or BigInt x to a mathematical value is represented as “the mathematical value of x” or R(x). The mathematical value of + 0F and -0f is 0
Simple conclusion:
- Number区分+0,- 0
- BitInt does not distinguish between
What is the difference between BigInt::sameValue and BigInt:samgeValueZero? Here’s a picture to illustrate:
No difference, what’s the more reasonable explanation? Perhaps inheriting from the same parent class??
summary
IndexOf is a product of ES5 and even earlier, includes is a product of ES6. Advanced products toward a more reasonable direction of development, reasonable.
As for why not upgrade indexOf, the historical baggage, the old code can’t make it unexpected.
Write in the last
Please go to the technical exchange groupCome here,. Or add my wechat Dirge-Cloud and take me to learn together.
reference
IsNaN isNaN “ten thousand word summary” stay up late to summarize 50 JS advanced knowledge points, all will you are god!!