Javascript equality operators - javascript

In David Flanagan's Javascript guide, there is a statement:
the == operator never attempts to convert its operands to boolean
So here I did a little test:
var a = false;
var b = ""; // empty string
a == b; //returns true
Looking at Abstract Equality Comparison Algorithm there is a point:
e. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
How can x and y be both true if y is string data type (without conversion)?

What happens under the hood is
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
Number(false) == ""
followed by
If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
Number(false) == Number("") -> 0 == 0
How can x and y be both true if y is string data type (without conversion)?
They are not both true, but after type coercion their values are equal.
the == operator never attempts to convert its operands to boolean
And that is correct, if you check the comparison algorithm you will find that types are never implicitly casted to Boolean.
References:
11.9.3 The Abstract Equality Comparison Algorithm
9.3 ToNumber

Related

Javascript/jQuery: Check if two values are equal regardless of data type?

I am have an if condition where I need to check if A has the same value as B irrespective of data type, like
if (A == B) {
//body of if statement
}
but the server check in validation will reject if == is present. It will ask to change that to === (but I can't change this).
How I can achieve this, where the possible values and types of A & B are
String, Number, null, '', undefined, NaN
Looks simple but may just be a logic error... :)
Fundamentally, there are valid use cases for == and so I would suggest finding whoever can change that rule and having them do so.
In the absense of that, you can write yourself a function that does what == does, which is called the abstract equality comparison algorithm, and then use that function instead of ==:
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
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.
The exact implementation of every abstract operation used above is clearly defined in the spec.
I found it,(Workaround)
A = A ? A.toString() : A;
B = B ? B.toString() : B;
if(A === B){
//Rock it
}

Can't understand the conditional execution flow [duplicate]

This question already has an answer here:
Javascript equality operators
(1 answer)
Closed 3 years ago.
A simple js snippet. Why does it always alert
'result is empty'
As per my understanding, if block should get executed since result!="" is true and alert
'result is not empty'.
<script>
var result = false;
if(result != "")
alert('result is not empty')
else
alert('result is empty')
</script>
It's because != does implicit type conversion. If you used the strict version, !==, it would do what you expect. But the loose version, !=, will convert both of those operands to numbers, and both "" and false convert to 0, so "" != false is false, because it ends up (through a series of convolutions) being 0 != 0.
This is laid out in detail in Abstract Equality Comparison algorithm in the specification:
ReturnIfAbrupt(x).
ReturnIfAbrupt(y).
If Type(x) is the same as Type(y), then
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, then
return the result of the comparison x == ToPrimitive(y).
If Type(x) is Object and Type(y) is either String, Number, or Symbol, then
return the result of the comparison ToPrimitive(x) == y.
Return false.
As we can see from the above, if we start out with false and "", then:
We follow Step 8, convert false to 0, and start again with 0 != ""
We follow Step 6, convert "" to 0, and start again with 0 != 0
We follow Step 3 and get the result false (because we're doing !=, whereas the algorithm is defined in terms of ==).
In javascript two falsy things can be equal, as in this case, where result != "" yields false.
You need to use an strict comparison, i.e. !== to make the comparison. result !== "" yields true.
Javascript checks for truthy values.
false != ""
is false
false !== ""
is true so you can try it.

Why === faster than == in JavaScript? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
See these tests:
== vs ====
== vs ===
Here's what javascript has to do for ===:
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
If x is NaN, return false.
If y is NaN, return false.
If x is the same Number value as y, return true.
If x is +0 and y is −0, return true.
If x is −0 and y is +0, return true.
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.
And here's what it has to do for ==:
If Type(x) is the same as Type(y), then
If Type(x) is Undefined, return true.
If Type(x) is Null, return true.
If Type(x) is Number, then
If x is NaN, return false.
If y is NaN, return false.
If x is the same Number value as y, return true.
If x is +0 and y is −0, return true.
If x is −0 and y is +0, return true.
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.
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.
Notice that if Type(x) equals Type(y) then the operators do the same thing. However, if they aren't, then the == might have to do various conversions whereas === just returns false.
For the links you gave, the types that are being compared are actually the same, so the two operators should perform about equally. Differences here would be based on implementation details - since they do different things, they can be optimized for differently. Theoretically, since === does less, one would think it would always be faster, but that doesn't appear to be the case for certain builds of Firefox, at least if those benchmarks are accurate.
However, see the difference if the types are different. When doing "hi" === {} you get ~66 million ops/second, but for "hi" == {} you only have ~4 million ops/second.
JavaScript is a weakly typed language, so it will apply type coercion wherever possible.
Equals Operator
// These are true
new Number(10) == 10; // Number.toString() is converted
// back to a number
10 == '10'; // Strings gets converted to Number
10 == '+10 '; // More string madness
10 == '010'; // And more
isNaN(null) == false; // null converts to 0
// which of course is not NaN
The Strict Equality Operator
It works like the normal equality operator, except that strict equality operator does not perform type coercion between its operands.
"" === "0" // false
0 === "" // false
0 === "0" // false
false === "false" // false
false === "0" // false
false === undefined // false
false === null // false
null === undefined // false
" \t\r\n" === 0 // false
The above results are a lot clearer and allow for early breakage of code. This hardens code to a certain degree and also gives performance improvements in case the operands are of different types.
So === faster than == in Javascript
Here is good Reference
=== compares if the values and the types are the same.
== compares if the values are the same, but it also does type conversions in the comparison. Those type conversions make == slower than ===.

JavaScript: Why is []==![]?

In JavaScript, I noticed that []==![] result is true. demo
I don't understand this result. Can you explain why?
[] is an array, but ![] is a boolean value. Whenever you try to compare two objects with different types with == both objects should be transformed into comparable objects (using ToNumber, see step 7. in 11.9.3). This is why [] == ![] yields true, the first empty array gets evaluated to false.
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 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.
However, if you use the strict type comparison operator === the result is false, since both types differ:
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
If x is NaN, return false.
If y is NaN, return false.
If x is the same Number value as y, return true.
If x is +0 and y is -0, return true.
If x is -0 and y is +0, return true.
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.

JavaScript truthiness in boolean to numbers comparison

I'm new to JavaScript and I'm trying to learn it from internet resources. While I'm aware that there will plenty of cr*p material, one thing most people seemed to agree is the truthiness of things in JS (just to give a example go here)
Now I found this odd thing in my experiments:
(true == 2) is false. why?
As far as I know, 2 is a non zero number, so it should be evaluated as true.
This is because when either operand of an equality operator is a number, in nearly all cases the other operand is converted to a number and then the result is compared. So you're ending up comparing 1 (converted from true) with 2, not true with true. The only exceptions to that rule are null, undefined, and objects whose default value (see off-topic below) is null or undefined; comparing a number to those returns false (even though Number(null) is 0; don't ask).
Details in the specification, Section 11.9.3: "The Abstract Equality Comparison Algorithm". This was the text of that section as of ES 5.1, but that link is to the currently editor's draft (which is what each year's snapshot specification is based on) and there have been several :
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
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.
NOTE: This step is replaced in section B.3.7.2.
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 BigInt and Type(y) is String, then
Let n be ! StringToBigInt(y).
If n is NaN, return false.
Return the result of the comparison x == n.
If Type(x) is String and Type(y) is BigInt, return the result of the comparison y == x.
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, BigInt, 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, BigInt, or Symbol, return the result of the comparison ? ToPrimitive(x) == y.
If Type(x) is BigInt and Type(y) is Number, or if Type(x) is Number and Type(y) is BigInt, then
If x or y are any of NaN, +∞𝔽, or -∞𝔽, return false.
If ℝ(x) = ℝ(y), return true; otherwise return false.
Return false.
Note: The !s in the above are not negations, they indicate that the following abstract operation never results in an abrupt completion. Details in this article about reading the spec.
If you wanted to check that they were both truthy or both falsy, you could use the bang (!) or double-bang (!!) idiom to coerce them both to booleans:
var a = true,
b = 2;
alert(a == b); // "false", 1 !== 2
alert(!!a == !!b); // "true", true === true
alert(!a == !b); // "true", false === false
a = false;
b = 0;
alert(a == b); // "true", 0 === 0
alert(!!a == !!b); // "true", false === false
alert(!a == !b); // "true", true === true
...but usually using == or != with booleans isn't ideal. But it does come up.
I tend to use the double-bang, but in JavaScript there's no reason to over the bang. (There's an argument for the double over the single in some other languages, though it's a weak one related to consistency with if (!!x). In JavaScript you never need the double-bang in the if (x) case, so...)
(Off-topic: The default value of most JavaScript objects is a string, though frequently one like "[object Object]" that ends up being NaN if you convert it to a number; but constructor functions can override that behavior via valueOf and toString. The default value of host objects is up to the host environment.)
The boolean true constant is promoted to a number, that being 1.
With non-strict comparison (==) if the operands are not of the same type, they will be casted/coerced and strictly compared, with first preference being to numbers if either operand is a number or boolean (MDN).
So true == 2 evaluates to Number(true) === 2 which is 1 === 2, which is false.
Of course you can always force things to compare as you want them to, which is explicit and can solve hard-to-find problems later on:
true === Boolean(2) is true.

Categories