Difference between javascript operator === and lodash method _.eq()? - javascript

Is there a difference between the === comparator in javascript and the _.eq() method in lodash?
_.eq() (Link)
Performs a SameValueZero comparison between two values to determine if
they are equivalent.
Update
Not sure if this checks on the same type, like the === operator.
7.2.10SameValueZero (x, y)#
The internal comparison abstract operation SameValueZero(x, y), where
x and y are ECMAScript language values, produces true or false. Such a
comparison is performed as follows:
If Type(x) is different from Type(y), return false. If Type(x) is
Number, then If x is NaN and y is NaN, return true. If x is +0 and y
is -0, return true. If x is -0 and y is +0, return true. If x is the
same Number value as y, return true. Return false. Return
SameValueNonNumber(x, y). NOTE SameValueZero differs from SameValue
only in its treatment of +0 and -0.
7.2.11SameValueNonNumber (x, y)#
The internal comparison abstract operation SameValueNonNumber(x, y),
where neither x nor y are Number values, produces true or false. Such
a comparison is performed as follows:
Assert: Type(x) is not Number. Assert: Type(x) is the same as Type(y).
If Type(x) is Undefined, return true. If Type(x) is Null, return true.
If Type(x) is String, then If x and y are exactly the same sequence of
code units (same length and same code units at corresponding indices),
return true; otherwise, return false. If Type(x) is Boolean, then If x
and y are both true or both false, return true; otherwise, return
false. If Type(x) is Symbol, then If x and y are both the same Symbol
value, return true; otherwise, return false. Return true if x and y
are the same Object value. Otherwise, return false.

Loadash _.eq checks the NaN equality as well.
_.eq(NaN, NaN) => true
NaN === NaN => false
https://github.com/lodash/lodash/blob/6cb3460fcefe66cb96e55b82c6febd2153c992cc/eq.js#L32
function eq(value, other) {
return value === other || (value !== value && other !== other)
}

Related

Is Object.is(x,y) faster than other comparisons?

So in JavaScript we have three equality comparison operators. I've been reading the ECMAScript specification and looking at how they work. Something struck me. The Object.is() built in function has less steps to it's comparison and it has a greater chance of terminating early than the other operators. So does this make Object.is() function faster than the other operators?
Here are the specification snippets:
Object.is()
If Type(x) is different from Type(y), return false.
If Type(x) is Number, then
a. If x is NaN and y is NaN, return true.
b. If x is +0 and y is -0, return false.
c. If x is -0 and y is
+0, return false.
d. If x is the same Number value as y, return true.
e. Return false.
Return SameValueNonNumber(x, y).
Loose equals ==
The comparison x == y, where x and y are values, produces true or
false. Such a comparison is performed as follows:
If Type(x) is the same as Type(y), then
a. Return the result of performing Strict Equality Comparison x === y.
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
If Type(x) is Number and Type(y) is String, return the result of the comparison x == ! ToNumber(y).
If Type(x) is String and Type(y) is Number, return the result of the comparison ! ToNumber(x) == y.
If Type(x) is Boolean, return the result of the comparison ! ToNumber(x) == y.
If Type(y) is Boolean, return the result of the comparison x == ! ToNumber(y).
If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
Return false.
Strict equals ===
The comparison x === y, where x and y are values, produces true or
false. Such a comparison is performed as follows:
If Type(x) is different from Type(y), return false.
If Type(x) is Number, then
a. If x is NaN, return false.
b. If y is NaN, return false.
c. If x is the same Number value as y, return true.
d. If x is +0 and y is -0, return true.
e. If x is -0 and y is +0, return true.
f. Return false.
Return SameValueNonNumber(x, y).
If someone who works on JavaScript compilers could answer that question, that would be great!
Less steps in the spec do not necessarily mean less steps in the implementation. All kinds of optimizations apply here. So in the end, all we can do is to actually race the horses! (in your real world usecase, some synthetic while(true) Object.is(1, 1); won't generate any useful results). If it is really (notably) faster, does it make your code better, e.g. is
Object.is(user.age, 3)
clearer than
user.age === 3
?

How and why [1,2,3] == "1,2,3" returns true in JavaScript?

I would like to know why this happens and what is the primitive value of "a"?
a = [1,2,3]
b = "1,2,3"
a==b //this returns true
As far as I know when doing this the primitive type of a is compared with b.
EDIT:
According to the section "Loose equality using =="
When you compare an object (a) with a string (b) the following rule is valid:
ToPrimitive(A) attempts to convert its object argument to a primitive value, by attempting to invoke varying sequences of A.toString and A.valueOf methods on A.
Undestanding how "ToPrimitive(A)" works was crucial.
It returns true because you are not using the strict comparison operator ===.
When using == you are actually doing [1,2,3].toString() === '1,2,3'
Equality (==) (source)
The equality operator converts the operands if they are not of the
same type, then applies strict comparison. If both operands are
objects, then JavaScript compares internal references which are equal
when operands refer to the same object in memory.
Identity / strict equality (===) (source)
The identity operator returns true if the operands are strictly equal
(see above) with no type conversion.
console.log('[1,2,3] == "1,2,3"', [1,2,3] == "1,2,3");
console.log('[1,2,3] === "1,2,3"', [1,2,3] === "1,2,3");
console.log('[1,2,3].toString() === "1,2,3"', [1,2,3].toString() === "1,2,3");
The Abstract Equality Comparison Algorithm (source)
The comparison x == y, where x and y are values, produces true or
false. Such a comparison is performed as follows:
1.If Type(x) is the same as Type(y), then
____a. If Type(x) is Undefined, return true.
____b. If Type(x) is Null, return true.
____c. If Type(x) is Number, then
________i If x is NaN, return false.
________ii If y is NaN, return false.
________iii If x is the same Number value as y, return true.
________iv If x is +0 and y is −0, return true.
________v If x is −0 and y is +0, return true.
________vi Return false.
____d. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in
corresponding positions). Otherwise, return false.
____e. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
____f Return true if x and y refer to the same object. Otherwise, return false.
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
4. If Type(x) is Number and Type(y) is String,
return the result of the comparison x == ToNumber(y).
5. If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.
6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
8. If Type(x) is either String or Number and Type(y) is Object,
return the result of the comparison x == ToPrimitive(y).
9. If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x) == y.
10. Return false.

Why undefined is not equal to zero in JavaScript?

I'm discovering odds of JavaScript comparisons. I wanted to find an example of how tricky comparisons may be, and how can cause bugs in some situations.
I thought about example where some input variable remains undefined, and is compared to zero. Because undefined is false when converted to Boolean, and zero is false when converted to Boolean I decided to test following code:
var x;
//Here x should be initialized but due to some circumstances is not
if(x == 0){
//This should run
}
Surprisingly...
Boolean(undefined) //false
Boolean(0) //false
x //undefined
x == 0 //false
Why it's like that?
This behaviour is in the specification for The Abstract Equality Comparison Algorithm
From the specification
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
If Type(x) is the same as Type(y), then ...
...
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
Return false.
As undefined and a number (0) is not of the same type, it's only in the third point where it mentions what to do if the left hand side is undefined.
Then, if the right hand side is null, it returns true, any other value, and it goes straight to 10., which says "return false".
Boolean(undefined) //false
Boolean(0) //false
Actually, The Boolean function returns false for all non-real values such as 0, null, undefined, ""(empty string), etc.
It does not mean that the undefined == 0

Javascript Comparison Operators != vs !== [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Javascript === vs == : Does it matter which “equal” operator I use?
Difference between == and === in JavaScript
I have two variables to compare.
Result should not be equal, in which condition i need to use != and !== ?
because when i use both operator it is working properly, but i need to know exactly what is the difference.
Human readable text about their differences
Using !== and === will do a more strict compare than ==/!=. The former will check if the objects being compared are of the same type, as well as if the values matches.
Using == will make it possible for an implicit cast to be made, see the below examples.
(0 == '0') // true
(0 === '0') // false
('' == 0 ) // true, the string will implicitly be converted to an integer
('' === 0 ) // false, no implicit cast is being made
What does the standard say?
11.9.6 The Strict Equality Comparison
Algorithm The comparison x === y, where x and y are values, produces true or false. Such a comparison
is performed as follows:
If Type(x) is different from Type(y), return false.
If Type(x) is Undefined, return true.
If Type(x) is Null, return true.
If Type(x) is Number, then
a. If x is NaN, return false.
b.If y is NaN, return false.
c. If x is the same Number value as y, return true.
d. If x is +0 and y is 0, return true.
e. If x is 0 and y is +0, return true.
f. Return false.
If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in
corresponding positions); otherwise, return false.
If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
Return true if x and y refer to the same object. Otherwise, return false. NOTE This algorithm differs from the SameValue Algorithm (9.12)
in its treatment of signed zeroes and NaNs.
11.9.3 The Abstract Equality Comparison Algorithm
The comparison x == y, where x and y are values, produces true or
false. Such a comparison is performed as follows:
If Type(x) is the same as Type(y), then
a. If Type(x) is Undefined, return t rue.
b. If Type(x) is Null, return true.
c. If Type(x) is Number, then
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.
d. If Type(x) is String, then return true if x and y are exactly
the same sequence of characters (same length and same characters in
corresponding positions). Otherwise, return false.
e. If Type(x) is Boolean, return true if x and y are both true or
both false. Otherwise, return false.
f. Return true if x and y refer to the same object. Otherwise, return false.
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y) .
If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
Return false
The difference is that the former (!=) version will coerce the two variables to be type compatible before the comparison. Hence:
"" == 0 -> true
"" === 0 -> false
The other version requires strict equality - the two values must both be of the same type and have the same value. Most of the time this is the one you should actually use.
In the case of objects strict equality means that they are actually the same object. A comparison between objects does not perform a field-by-field comparison of the contents of the object.
See https://developer.mozilla.org/en/JavaScript/Reference/Operators/Comparison_Operators for more.
The difference is that !== returns true only when variables have the same type and are not equal.

How does string equality work in JavaScript?

There are plenty of tutorials for == and === so please don't guide me to a basic tutorial, my question is a bit more specific:
For example http://www.w3schools.com/jsref/jsref_obj_string.asp states that:
Syntax:
var txt = new String("string");
// or more simply:
var txt = "string";
Good, but what about this?
alert(new String("a") == new String("a")); // false
alert("a" == "a"); // true
var a = new String("a");
var b = new String("a");
alert(a == b); // false
var c = "a";
var d = "a";
alert(c == d); // true
alert(c === d); // true
alert (a === c); // false
Of course nobody calls new String() anyway, but is it something about the equality failing because new String() is handled as an object not as a string?
And of course W3Schools is not the most trusted source but I would have expected all of the above alerts to say true.
Please explain.
The "surprising results" come from the way Javascript handles equality for Objects, plus the confusion that arises between string literals and String objects. From the Mozilla reference guide for the == operator:
If the two operands are not of the same type, JavaScript converts the
operands then applies strict comparison. If either operand is a number
or a boolean, the operands are converted to numbers if possible; else
if either operand is a string, the other operand is converted to a
string if possible. If both operands are objects, then JavaScript
compares internal references which are equal when operands refer to
the same object in memory.
You can experience the same behavior with numbers:
new Number(5) == new Number(5) // false
And clarify your mind by:
typeof "string" // string
typeof new String("string") // object
String literals, which are primitive value types, are different from new String objects, which are entities with distinct references wrapping those values. See Predefined Core Objects in Mozilla's JavaScript docs for details.
So you're right in that comparison is handled differently for literals and for objects, simply because one compares their values while the other compares references.
You are correct that in your example case you are comparing 2 different object references. Within the language specification you'll find this algorithm. The portion you are looking for is section 1 f.
11.9.3 The Abstract Equality Comparison Algorithm
11.9.3 The Abstract Equality Comparison Algorithm
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as
follows:
1. If Type(x) is the same as Type(y), then
a. If Type(x) is Undefined, return true.
b. If Type(x) is Null, return true.
c. If Type(x) is Number, then
i. If x is NaN, return false.
ii. If y is NaN, return false.
iii. If x is the same Number value as y, return true.
iv. If x is +0 and y is -0, return true.
v. If x is -0 and y is +0, return true.
vi. Return false.
d. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same
length and same characters in corresponding positions). Otherwise, return false.
e. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
f. Return true if x and y refer to the same object. Otherwise, return false.
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
4. If Type(x) is Number and Type(y) is String,
return the result of the comparison x == ToNumber(y).
5. If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.
6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
8. If Type(x) is either String or Number and Type(y) is Object,
return the result of the comparison x == ToPrimitive(y).
9. If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x) == y.
10. Return false.
Also take notice that steps 8 and 9 which makes dealing with String objects a bit cleaner.
alert(new String("a") == "a"); // true
alert("a" == new String("a")); // true

Categories

Resources