Javascript ES6. Difference between === and Object.is [duplicate] - javascript

This question already has answers here:
Object.is vs ===
(6 answers)
Closed 5 years ago.
We know what the difference between == and === is - basically, === prevents Javascript engine to convert one of the parameter for making both parameters of the same type. But now, in ES6, came a new operator - Object.is which is a bit confusing (or maybe === is now confusing..)
From Mozila website (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness) we can see the difference:
Sameness Comparisons:
x y == === Object.is
+0 -0 true true false
NaN NaN false false true
So, for me, looks like Object.is is even more strict in comparing parameters, if so, question raises - how unstrict was === (called "Strict Equality") :)

From the article you linked:
When to use Object.is versus triple equals
Aside from the way it treats NaN, generally, the only time Object.is's special behavior towards zeros is likely to be of interest is in the pursuit of certain meta-programming schemes, especially regarding property descriptors when it is desirable for your work to mirror some of the characteristics of Object.defineProperty. If your use case does not require this, it is suggested to avoid Object.is and use === instead. Even if your requirements involve having comparisons between two NaN values evaluate to true, generally it is easier to special-case the NaN checks (using the isNaN method available from previous versions of ECMAScript) than it is to work out how surrounding computations might affect the sign of any zeros you encounter in your comparison.

Via MDN:
This is also not the same as being equal according to the === operator. The === operator (and the == operator as well) treats the number values -0 and +0 as equal and treats Number.NaN as not equal to NaN.

Related

How to find, what kind of a Javascript error I have?

Quick and a silly question that got me confused.
What kind of error occurs if I use an assignment statement instead of a comparison statement? I need to check if the value of the counter variable is equal to 5.
The code:
if (counter = 5) { /* ==SOME CODE==*/}
VS
if (counter == 5) { /* ==SOME CODE==*/}
The easiest way to pick-up this problem is to reverse the order of the comparison.
Instead of:
if (someVar == 5)
Use:
if (5 == someVar)
This way, if you mess it up, you'll get an assignment error, since you can't assign a different value to the number 5. You can assign a different value to a number object that happens to hold the number 5, but you can't change the 5 itself. ;)
What kind of error occurs if I use an assignment statement instead of a comparison statement?
In your example i assume that a browser would not throw any errors.
I tested https://validatejavascript.com/ with this code:
let counter = 3;
if (counter = 5) {
alert('Will this ever show or always?');
}
A linter might generate a warning - for exmaple
validatejavascript.com threw: 3:5 error Unexpected assignment within an 'if' statement. (no-cond-assign) and
jshint.com threw: Expected a conditional expression and instead saw an assignment.
And based on your comment:
But I need to check if the value of the counter variable is equal to 5.
A simple assignment operator (=) is used to assign a value to a variable.
What you are looking for are operators for Equality comparisons and sameness
JavaScript provides three different value-comparison operations:
=== - Strict Equality Comparison ("strict equality", "identity", "triple equals")
== - Abstract Equality Comparison ("loose equality", "double equals")
Object.is provides SameValue (new in ES2015).
Which operation you choose depends on what sort of comparison you are
looking to perform. Briefly:
double equals (==) will perform a type conversion
when comparing two things, and will handle NaN, -0, and +0
specially to conform to IEEE 754 (so NaN != NaN, and -0 == +0);
triple equals (===) will do the same comparison as double equals
(including the special handling for NaN, -0, and +0)
but without type conversion; if the types differ, false is returned.
Object.is does no type conversion and no special handling for NaN, -0,
and +0 (giving it the same behavior as === except on those special
numeric values).
Note that the distinction between these all have to do with their
handling of primitives; none of them compares whether the parameters
are conceptually similar in structure. For any non-primitive objects x
and y which have the same structure but are distinct objects
themselves, all of the above forms will evaluate to false.

How Number.Nan works in this function? [duplicate]

This question already has answers here:
What is the rationale for all comparisons returning false for IEEE754 NaN values?
(12 answers)
Closed 6 years ago.
Why does NaN === NaN return false in Javascript?
> undefined === undefined
true
> NaN === NaN
false
> a = NaN
NaN
> a === a
false
On the documentation page I see this:
Testing against NaN
Equality operator (== and ===) cannot be used to test a value against NaN. Use isNaN instead.
Is there any reference that answers to the question? It would be welcome.
Strict answer: Because the JS spec says so:
If Type(x) is Number, then
If x is NaN, return false.
If y is NaN, return false.
Useful answer: The IEEE 754 spec for floating-point numbers (which is used by all languages for floating-point) says that NaNs are never equal.
This behaviour is specified by the IEEE-754 standard (which the JavaScript spec follows in this respect).
For an extended discussion, see What is the rationale for all comparisons returning false for IEEE754 NaN values?
Although either side of NaN===NaN contains the same value and their type is Number but they are not same. According to ECMA-262, either side of == or === contains NaN then it will result false value.
you may find a details rules in here-
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

Why this JavaScript includes() feature make sense? [duplicate]

This question already has answers here:
Why does [NaN].includes(NaN) return true in JavaScript?
(5 answers)
Closed 24 days ago.
I'm learning about includes() feature, and I found this code
[NaN].includes(NaN) //True
But
NaN === NaN // False
Why this is posible?
Using equality NaN === NaN and using includes [NaN].includes(NaN) are basically asking two different questions:
Equality - are this things that have the same name are actually equal?
NaN is an amorphic entity, which describes the concept of not being a numeric value, and doesn't actually have a value you can compare. Equality uses the Strict Equality Comparison, and defines that a comparison x === y with NaN on any side of the equation is always false:
a. If x is NaN, return false.
b. If y is NaN, return false.
Includes - do I have something with that "name" in the array?
However, to search for a NaN in an array, and to keep the to Array#includes signature of passing only one param, and not a callback, we need a way to "name" what we are searching for. To make that possible, ccording to the Array#includes definition in the ECMAScript 2016 (ECMA-262) docs:
The includes method intentionally differs from the similar indexOf
method in two ways. First, it uses the SameValueZero algorithm,
instead of Strict Equality Comparison, allowing it to detect NaN
array elements. Second, it does not skip missing array elements,
instead treating them as undefined.
The definition of SameValueZero(x, y) states that when comparing:
If x is NaN and y is NaN, return true.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN
Unlike all other possible values in JavaScript, it is not possible to rely on the equality operators (== and ===) to determine whether a value is NaN or not, because both NaN == NaN and NaN === NaN evaluate to false. Hence, the necessity of an isNaN function.
[ NaN ].includes(NaN) what this does is to check if NaN is in the [ ].
NaN === NaN and NaN == NaN will still return the same value which is false. What you just have to know is that the includes methods checks if a value is the array it is been called on. Behind the hood i think the includes Array method does it's checks using typeof()
typeof(NaN) // number
[ NaN ].includes(NaN) // true
typeof("1") // string
[ 1 ].includes("1") // false
typeof(1) // number
[ 1 ].includes(1) // true
this is according to the SameValueZero Algorithm that the includes method uses. Internally it checks the type of the value

Why does angular.isNumber(NaN) return true? [duplicate]

This question already has answers here:
Why does typeof NaN return 'number'?
(21 answers)
Closed 7 years ago.
NaN represents Not-A-Number.
It appears that angular.isNumber thinks it is a number. (angularjs 1.4.2)
Why does angular.isNumber return true for NaN input?
thanks
Quoting IgorMinar, Angular Developer in this exact question:
$ node
> typeof NaN
'number'
It kind of makes sense if you squint with both eyes and plug your
ears.
If you deliberately use NaN in your app, you should use isNaN instead
of angular.isNumber.
I'm inclined to say that the current behavior, even though a bit
surprising, is consistent with how NaN is being treated in javascript.
If you have some good arguments for changing the behavior please share
them with us.
So the question really goes for the javascript standard itself not for Angular
And to answer this question we must go to ECMAScript 5 specification of number type, of course it says:
4.3.20 Number type
set of all possible Number values including the special “Not-a-Number”
(NaN) values, positive infinity, and negative infinity
4.3.23 NaN
number value that is a IEEE 754 “Not-a-Number” value
So yes, according to the latest ECMAScript Specification i'm a number
Here's the best way that I can think of to explain this.
Although the value of NaN represents something that is not a number, the value NaN itself is still a number type (in the type system sense).
It's also a defined value for a floating point number in IEEE 754, which is what JavaScript uses for numbers. It is sensible that values infinity and NaN would be number types.
The ECMA spec defines NaN as a IEEE 754 Not-a-Number number value. One reason for the NaN global being a number are comparison purposes. It is also needed to represent undefined numerical results, like the value of Math.sqrt(-1). So it’s not particularly AngularJS specific. Consider the following:
typeof NaN === "number" // true
typeof NaN === typeof NaN // true
typeof NaN === typeof 123 // true
NaN === NaN // false
isNaN(NaN) // true
isNaN(123) // false
isNaN('123') // false
isNaN('|23') // true
So isNumber returns true for NaN because it is a Number. To check for numerics, use isNaN().
Most likely angular just uses the type of what you pass in. if the type is number then it returns true.
If you want to know if something is a number (excluding NaN) you can do the following.
function isNumber(val){
return angular.isNumber(val) && (val == val);
}
This works by first determing if val is a number. If it is check to see if it's NaN.
NaN is not equal to itself (or any other number for that matter).
it's not related to angular, it's JavaScript
try this
typeof NaN
it will return number
There are really two meanings of "number" here:
the abbreviation "NaN" means that there is no meaningful answer to a particular mathematical operation; you could say "no such number"
however, every value in a language like JS has a type, and the type of data which goes into and out of mathematical operations is known in JS as "number"; thus when JS wants a special value to say that a mathematical operation has no answer, that special value is a special number
Note that this apparent contradiction is less obvious in other languages, because JS is unusual in having only one numeric type, rather than (at least) integer and real/float types. Having NaN as a floating point value is standard across pretty much all modern languages, but because of the word "number", it perhaps seems more surprising in JS.
The Angular function is one of a set of utilities for testing the type of a value. The documentation for it mentions that it returns true for infinities and NaN, and points to the standard isFinite function for when that's not desirable.

Does operand order make any difference when evaluating equality or identity in JavaScript?

Question: does operand order make any difference when evaluating equality or identity in JavaScript?
In code, is (0 == value) faster or more correct than (value == 0)? (Note that this question is equally valid for the identity operator, ===.)
Since both the equality and identity operators are commutative, I don't believe the operand order should make a difference in evaluation performance, unless there's some inherent benefit to the left-side literal in the computation of the equality algorithm itself. The only reason I wonder is that I recently used Google's Closure Compiler to boil down some JavaScript, and noticed that
if (array.length == 0 && typeof length === 'number') {
had been compiled to
if(0 == b.length && "number" === typeof c) {.
In both equality expressions—one loose and one strict—Closure has reversed the order of my operands, placing a Number literal and a String literal on the left–hand sides of their respective expressions.
This made me curious.
I read through the Equality Operators section of the ECMAScript 5.1 Language Specification (section 11.9, pp. 80–82) and found that while the equality algorithms start by examining the left–hand operands first, there's no indication that it's faster or better to use a literal as that operand.
Is there something about ECMAScript's type–checking that makes examination of literals optimal? Could it be some optimization quirk in the Closure compiler? Or perhaps an implementation detail in an older version of ECMAScript's equality algorithm which has been nullified in this newer version of the spec?
A lot of time people code with the variable on the right as a style convention. Main reason it can catch errors with sloppy coding.
The following code is most likely a bug, but the if statement will evaluate to true.
if( n = 1 ) { }
and this will throw an error
if( 1 = n ) { }
http://jsperf.com/lr-equality
I can't really give you an explanation, but you can check the numbers. They seem to be equal (now).

Categories