Exact behaviour of == and === operator in JavaScript - javascript

While writing simple snippet for comparison in JavaScript I observed some weird behavior.
Case 1:
typeof(window.WHTStatement.DDL_TPTypeID.size()) ==> "number"
typeof(window.WHTStatement.Txt_TPTypeValue.size()) ==> "number"
window.WHTStatement.DDL_TPTypeID.size() == 1 == window.WHTStatement.Txt_TPTypeValue.size()
returns true -- OK
Case 2:
window.WHTStatement.DDL_TPTypeID.size() === 1 == window.WHTStatement.Txt_TPTypeValue.size()
returns true -- OK
Case 3:
window.WHTStatement.DDL_TPTypeID.size() === 1 === window.WHTStatement.Txt_TPTypeValue.size()
returns false, why?
What exactly happening here in case 3. Can somebody elaborate?

Unlike Python, in JS x == y == z is not equal to x == y && y == z but (x == y) == z. So you are actually comparing a boolean to a number which obviously fails in a type check.
The == comparison worked because 1 == true is true.

Related

Why does 1 == 1 == 1, but not 'A' == 'A' == 'A' [duplicate]

This question already has answers here:
Javascript if (x==y==z): [duplicate]
(2 answers)
Closed 2 years ago.
I'm trying to write a flexible query logic based on a config payload, e.g:
{
"test": "( fieldA == fieldB == fieldC )"
}
When my app replaces 'fieldA', 'fieldB' and 'fieldC' value with text data, the result is always false.
This clearly has to do with me confusing the way javascript runs the comparison (it must have something to do with data types and math ordering), but can anyone explain this with a simple example for alphanumeric values?
e.g. 'John Smith' == 'John Smith' == 'John Smith' is always false;
x == y == z does not do what you think :
it translates to (x == y) == z.
With the quirks of javascript's == operator :
1 == 1 and 'A' == 'A' both translate to true
however : true == 1 returns true, while true == 'A' doesn't
You probably want to rewrite your condition to :
(x == y) && (x == z)
and very probably want to use the unambiguous === operator :
(x === y) && (x === z)
to avoid pitfalls such as the one you falled upon (true == 1 checks, but not true === 1)
A==B==C or A==A==A is legally allowed.
But the problem is, A==C never happens or in your case fieldA==fieldC never happens. Hence this leads to ambiguity

if var a = true then a == 1 is true but a == 2 is false. Why? [duplicate]

This question already has answers here:
Javascript: the confuse about comparison "2 == true"
(2 answers)
Closed 5 years ago.
if var a = true then a == 1 is true but a == 2 is false. Why? I understand that in javascript boolean expressions 0 casts to false and 1 casts to true. But what about the other integers. Why the above behavior?
Why? I understand that in javascript boolean expressions 0 casts to
false and 1 casts to true.
Because Number(true) => 1
As per spec of abstract equality expression evaluation
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
Hence a is first coerced into a Number and then compared with 1.
when you use == or != in js,the operands will be converted to the same type before making the comparison.when converting:
if there is a Boolean, true will be turned to 1 and false turned to 0;
var a = true;
a == 1;// a turned to 1 before compare,so true
a == 2;// a turned to 1 before compare,so false
This is to do with coercion. In the a == 1 scenario, a is coerced into a an integer to compare again 1, true is coerced to 1. In the second example, a is again coerced to 1, so it doesn't equal 2.
Further reading on coercion
You may convert 1 to True and True to 1 but you can't convert other numerics to True.
That's probably inherited from binary world and it makes sense, because in binary 0 is false and 1 is true. Exactly, that is how type conversion been done for boolean types in javascript as well while comparing.
For boolean there are only 2 possibles, true or false. Hence in number/binary system 0 and 1 are apt to represent them.
Well because 0 = false and 1 = true. There are only two values for a boolean: true/false. So what should 2 be?
var has no type, it can be everything. Please consider also the == vs === operator.
var x = 1;
console.log(x === true);
console.log(x == true);
x = 2;
console.log(x === true);
console.log(x == true);
x = 0;
console.log(x === false);
console.log(x == false);
x = -1;
See the example: http://jsfiddle.net/2aqGS/146/

Javascript if (x==y==z): [duplicate]

This question already has answers here:
Double structural equality operators: if(a==b==c)
(2 answers)
Closed 8 years ago.
I've got 3 random numbers (in this specific case between 1 and 7 but it doesn't really matter).
I want to check whether I got "three of a kind" by using
if (x==y==z) {
code
}
The problem is that when x==y and z==1 x==y==z will return true. How do I check whether x, y and z actually got the SAME value?
Example: 5==5==1 will return true, how do I check for 5==5==5 specifically? (Excluding 5==5==1)
By doing a proper comparison:
x === y && y === z
// due to transitivity, if the above expression is true, x === z must be true as well
x==y==z is actually evaluated as
(x == y) == z
i.e. you are either comparing true == z or false == z which I think is not what you want. In addition, it does type conversion. To give you an extreme example:
[1,2,4] == 42 == "\n" // true
The problem is that when x==y and z==1, x==y==z will return true.
Yes, because x == y will be true, so you compare true == 1. true will be converted to the number 1 and 1 == 1 is true.
You should check with separate && operations
if(x == y && x == z){
//all are equal
}

Why does 1==1==1 return true, "1"=="1"=="1" return true, and "a"=="a"=="a" return false? [duplicate]

This question already has answers here:
How does (A == B == C) comparison work in JavaScript?
(6 answers)
Closed 8 years ago.
function a() { return (1 == 1 == 1); }
function b() { return ("1" == "1" == "1"); }
function c() { return ("a" == "a" == "a"); }
I tested the above code in Chrome's console and for some reason, a() returns true, b() returns true, and c() returns false.
Why is this so?
Because you are comparing the (boolean) result of the first equality with the (non-boolean) third value.
In code, 1 == 1 == 1 is equivalent to (1 == 1) == 1 is equivalent to true == 1.
This means the three methods can be written more simply as:
function a() { return (true == 1); }
function b() { return (true == "1"); }
function c() { return (true == "a"); }
These comparisons work according to these rules (emphasis mine):
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 string operand is
converted to a number if possible. If both operands are objects, then
JavaScript compares internal references which are equal when operands
refer to the same object in memory.
So what happens in c is that "a" is converted to a number (giving NaN) and the result is strictly compared to true converted to a number (giving 1).
Since 1 === NaN is false, the third function returns false. It's very easy to see why the first two functions will return true.
Because 1 == true
But "a" != true
So basically what happens is that
1 == 1, "1" == "1" and "a" == "a" are all evaluated to be true and then compared to the next value.
The string "1" is converted to a number (1) prior to being compared to true and is thus also considered to be equal to true.
Now, the "WHY?!?!" question is explained by the fact that Javascript has its roots in the C-family of languages. In which any number, other than 0 is considered to be a valid true boolean. :-/
Because 1 and "1" are both converted to true, as numbers. This is not the case with "a". Therefore:
("1" == "1" == "1")
evaluates to
(("1" == "1") == "1")
which evaluates to
(true == "1")
Similarly,
("1" == 1 == "1")
is also true, or any combination thereof. In fact, any non-zero number when converted to a boolean is true.
Whereas, "a" does not evaluate to true.
It's because JavaScript is a weakly typed language. This means that it is not expressive enough to talk about types, and in fact implicitly coerces values to belong in types to which they have no semantic relation. So, (1 == 1) == 1 evaluates to true because (1 == 1) correctly evaluates to true, so that JavaScript evaluates (true) = 1. In particular, it is turning 1 to a boolean (or true to a number -- I forget which, but the result is effectively the same).
The point is that JavaScript is turning one type of value into another type of value behind your back.
Your question shows why this is a problem: ('a' == 'a') == 'a' is false, because ('a' == 'a') is true, and JavaScript ends up comparing (true) == 'a'. Since there is just no sensible way to turn a Boolean into a letter (or a letter into a boolean), that statement is false. Of course, that breaks referential transparency for (==).
It's true that (1 == 1) == 1. Then it will be true == 1, but not in a == a == a.
Boolean handled as bits, each bit stands for true or false ( 1 for true, 0 for false )
so that 1 stands for true, and 0 stand for false
and 1 == 1 == 1 will be like (1 == 1) == 1, true == 1, true
while 'a' == 'a' == 'a' will be ('a' == 'a') == 'a', true == 'a', false
BONUS: 0 == 1 == 0, 1 == 0 == 0 and 0 == 0 == 1 returns true

When is (true == x) === !!x false?

JavaScript has different equality comparison operators
Equal ==
Strict equal ===
It also has a logical NOT ! and I've tended to think of using a double logical NOT, !!x, as basically the same as true == x.
However I know this is not always the case, e.g. x = [] because [] is truthy for ! but falsy for ==.
So, for which xs would (true == x) === !!x give false? Alternatively, what is falsy by == but not !! (or vice versa)?
"So, for which xs would (true == x) === !!x give false?"
Any x where its Boolean conversion is not the same as its conversion by the Abstract Equality Comparison Algorithm.
An example is a string with only whitespace:
var x = " ";
Its Boolean conversion is true (as is the case with any non-empty string), but its == comparison is false because a string with only white space will be converted to the number 0, and the true value will be converted to the number 1, and those values are not equal.
x == true; // false
!!x; // true
or to show the ultimate values the == is comparing:
Number(true) == Number(x);
// 1 == 0
1 == 0; // false
and to show the result of !!x, it would be equivalent to this:
Boolean(x); // true
So your original expression could crudely be seen as the following:
var x = " ";
(Number(true) == Number(x)) === Boolean(x);
// ( 1 == 0 ) === true
// ( false ) === true
false === true; // false
I say "crudely" because this certainly doesn't capture all the detail of the algorithm linked above, and won't be the same for all values provided to the operands.
To understand how == treats its operands, you really need to study the algorithm a bit.
Loose equality has nothing to do with truthiness.
The rules for loose equality basically involve comparing the results of the .valueOf() function for each object.
For more details, see the spec.

Categories