This question already has answers here:
Implied string comparison, 0=='', but 1=='1'
(6 answers)
Closed 7 years ago.
I am curious how
'' == '0' // false
left side is a blank string and right side has string with value 0 so its fine its is false.
But
0 == '' // true
how blank string equals to zero, both are typed different as well as value.
similar
false == 'false' // false
left is false , but we are not equating (===) type of value , its just has value false so it should be true ? but why it is false.
Could we explain the same ?
The left operand is of the type Number.
The right operand is of the type String.
In this case, the right operand is coerced to the type Number:
0 == Number('')
which results in
0 == 0
The following values are always falsy:
false 0 (zero)
"" or '' (empty string)
null
undefined
NaN (a special Number value meaning Not-a-Number!)
I found a nice table explaining what works and what not with the == operator.
Here is the link to the tables also containing === and if().
Related
This question already has answers here:
In JavaScript, why is "0" equal to false, but when tested by 'if' it is not false by itself?
(15 answers)
Closed 3 years ago.
The question says it all as I understand !!false = false
Then if
0 == false // true
'0' == false // true
why
!!0 == false
!!'0' == true
string zero ('0') is a truthy value
!!'0' == true
!'0' -> !false -> true
So you're actually doing
true == true
It looks like you stumbled across the importance of the === operator.
'0' == false; // true
'0' === false; // false
Boolean('0'); // true
typeof('0'); // string
typeof(!'0'); // boolean
!'0' === false; // true
!!'0' === false // false
The first negation converts string '0' to a boolean by calling of abstract function ToBoolean. According to JavaScript specification, only 7 values are evaluated/coerced/converted to false i.e are falsy:
null, undefined, NaN, Empty String, +0, -0, and false.
So, '0' is evaluted to a truthy, !'0' to false and !!'0' to true.
PS: Another cases of why '0' == false is evaluated to true is raised after the original question by the OP in a comment below. Even though not relevant to the original post, here is the explanation:
In the specification, section Abstract Equality Comparison reads: "When evaluating x == y, if the type of y is Boolean, first convert y to Number and then do the comparison again".
So Number(false) is evaluated to 0. In the next comparison run, string '0' is compared with number 0 i.e '0' == 0. The spec says convert the string to number and do the comparison again: 0 == 0.
This question already has answers here:
Why is "0" == [] false? [duplicate]
(4 answers)
Empty arrays seem to equal true and false at the same time
(10 answers)
Closed 4 years ago.
I were trying to play around the equal to == operator in Javascript, and I got the following results:
0 == "0" // true
and also
0 == [0] // true
HOWEVER:
"0" == [] // false
Honestly, this is kind of confusing for me since I have no Javascript-background.
Also, I noticed that:
"0" == [0] // true
and that is also applicable for other values:
1 == [1] // true
1 == "1" // true
"1" == [1] // true
101 == "101" // true
101 == [101] // true
"101" == [101] // true
So it seems to be about comparing 0 with an empty array [].
What is logic behind it?
If you see the Loose equality using == chart on Mozila Developer Network here at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness you can see that
If Operand A is string in your case "0" and Operand B is Object in your case [] then Operand B will be converted to primitive type like new String([]) returns ""
A == ToPrimitive(B)
Then if we try,
> typeof "0"
"string"
> typeof []
"object"
> "0"=="" // it will return false
If you try with
> 0==[] // it will return true
It happens because of type coercion (using double =). Basically when comparing variables that are not of equal types, javascript tries and covert them to the same type and the compare them. To avoid this use triple equals (===) when comparing variables.
To know more about javascript I recommend these books (free online!)
https://github.com/getify/You-Dont-Know-JS
but if you're interested in this topic specifically you can read this one:
https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch4.md
PS. Down at the end is exactly your example explained in detail.
Good luck!
It is working based Abstract equality comparison algorithm. Let me pick a single example from yours and explain how it is returning the results,
0 == [0]
So the main aim of AECA is to bring the lhs and rhs to a same type. Based on the algorithm, internally recursive steps would happen to make both the sides of same type.
i] 0 == [0]
ii] 0 == toPrimitive([0])
iii] 0 == '0'
iv] 0 == toNumber('0')
v] 0 == 0
vi] true
To put it simply, javascript will try most of the times to convert the sides of the equality to numbers if they are of different type.
For object, it will however call the abstract operation toPrimitive (with a hint of default). That operation calls .valueOf and then .toString on the result if it's still not a primitive ( meaning something else than an object).
0 == "0" => 0 == 0 => true
0 == [0] => 0 == "0" ( .valueOf returns [0] so .toString is used)
"0" == [] => "0" == "" => false ( they have the same type so the string must be the same to be true)
0 == [] => 0 == "" => 0 == 0 : true
The full resource is here:
https://www.ecma-international.org/ecma-262/8.0/#sec-abstract-equality-comparison
This question already has answers here:
Why does ('0' ? 'a' : 'b') behave different than ('0' == true ? 'a' : 'b') [duplicate]
(6 answers)
Closed 8 years ago.
I have the following JavaScript/jQuery code:
if (isVariance && value)
tableCell.addClass('NonZeroVariance');
Where:
isVariance == true and value == "0.00".
(isVariance && value) == "0.00".
(isVariance && !!value) == true.
The if condition evaluates to true, and the class is added to tableCell.
So, my expectation was that zero would be interpreted as false, and that "0.00" would be evaluated as false. But that's not what happens here. Can someone tell me why?
Yes, it appears that value is a string. And while the number 0.00 will evaluate to false, the string "0.00" evaluates to true.
The solution is to first convert the string to a number, and then perform the same test.
value = Number(value);
if (isVariance && value)
tableCell.addClass('NonZeroVariance');
EDIT:
The reason that the string "0.00" evaluates to true, is because: The result is false if the argument is the empty String (its length is zero); otherwise the result is true. - http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/
To the best of my knowledge, (x == false) should do the same thing as !x, as both of them try to interpret x as a boolean, and then negates it.
However, when I tried to test this out, I started getting some extremely strange behavior.
For example:
false == [] and false == ![] both return true.
Additionally
false == undefined and true == undefined both return false, as does
false == Infinity and true == Infinity and
false == NaN and true == NaN.
What exactly is going on here?
http://jsfiddle.net/AA6np/1/
It's all here: http://es5.github.com/#x11.9.3
For the case of false == []:
false is converted to a number (0), because that is always done with booleans.
[] is converted to a primitive by calling [].valueOf().toString(), and that is an empty string.
0 == "" is then evaluated by converting the empty string to a number, and because the result of that is also 0, false == [] is true.
For the case of false == ![]:
The logical not operator ! is performed by returning the opposite of ToBoolean(GetValue(expr))
ToBoolean() is always true for any object, so ![] evaluates to false (because !true = false), and therefore is false == ![] also true.
(false == undefined) === false and (true == undefined) === false is even simpler:
false and true are again converted to numbers (0 and 1, respectively).
Because undefined cannot be compared to a number, the chain bubbles through to the default result and that is false.
The other two cases are evaluated the same way: First Boolean to Number, and then compare this to the other number. Since neither 0 nor 1 equals Infinity or is Not A Number, those expressions also evaluate to false.
The abstract equality algorithm is described in section 9.3 of the specification.
For x == y where x = false and y = []:
Nope. Types are not equal.
Nope, x is not null.
Nope. x is not undefined.
Nope, x is not a number
Nope, x is not a string.
Yes, x is a boolean, so we compare ToNumber(x) and y.
Repeat the algorithm, x=0 and y=[].
We end at step 8:Type(x) == number. and Type(y) == object.
So, let the result be x == ToPrimitive(y).
ToPrimitive([]) == ""
Now, repeat the algorithm again with x=0 and y="". We end at 4: "return the result of the comparison x == ToNumber(y)."
ToNumber("") == 0
The last repetition of the algorithm ends at step 1 (types are equal). By 1.c.iii, 0 == 0, and true is returned.
The other results can be obtained in a similar manner, by using the algorithm.
false == []
Using == Javascript is allowed to apply conversions. The object will convert into a primitive to match type with the boolean, leaving an empty string. The false will convert into a number 0. The compares the empty string and the number 0. The string is converted to a number which will be 0, so the expression is "true"
![]
Javascript converts the object to the boolean true, therefore denying true ends being false.
false == undefined true == undefined
false == Infinity and true == Infinity
false == NaN and true == NaN
Again a bit of the same! false is converted to 0, true to 1. And then, undefined is converted to a number which is... NaN! So false in any case
I would recommend to use === !== as much as you can to get "expected" results unless you know very well what you are doing. Using something like Boolean(undefined) == false would also be nice.
Check ECMAScript specifications for all the details when converting stuff.
This question already has answers here:
Why does ('0' ? 'a' : 'b') behave different than ('0' == true ? 'a' : 'b') [duplicate]
(6 answers)
Closed 8 years ago.
Can anyone explain why here a = [] ? 1 : 2 a will be equal to 1 and here b = [] == true ? 1 : 2 b will be equal to 2
A very similar case is handled in Why does ('0' ? 'a' : 'b') behave different than ('0' == true ? 'a' : 'b').
In short:
When you have a single value that is evaluated in a boolean context, it is passed to ToBoolean to be converted to a boolean value.
If you compare values with == though, the algorithm in section 11.9.3 of the ECMAScript specification takes place. In this algorithm, both operands are converted to either strings or numbers and these values are compared.
More detailed explanation
a = [] ? 1 : 2
The condition is converted to a boolean by calling ToBoolean(GetValue(lref)). Now I assume that for objects, GetValue just returns the object itself and all objects evaluate to true.
Since arrays are just objects, the result of this expression is 1.
b = [] == true ? 1 : 2
As already said, quite some type conversion is going on here.
First, true is converted to a number:
7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
false is converted to 0 and true is converted to 1.
So we have
[] == 1
Then step 9 applies:
9. If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x) == y.
That means [] is converted to a primitive value (string or number). If you follow the ToPrimitive function (and section 8.12.8), you'll find out that arrays are converted to strings, by concatenating their elements with ,. Since an empty array as no elements, the result is an empty string.
So we end up with
"" == 1
Then step 5 applies:
5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
An empty string is converted to 0, hence 0 == 1 is false and the conditional operator returns 2.
Because an array is an object, and when an object is evaluated in the context of a boolean comparison, it is "truthy", but not exactly true.
In the first example the array is being converted to a Boolean which yields true as it's not null, undefined, "", 0 or false.
In the second example you're getting a type conversion because of the equals operator. From mdn:
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.
Tried the following in the console:
Number(true) //gives 1
Number([]) //gives 0
So when converted to numbers these are not equal.
In a = [] ? 1 : 2, it returns 1 if [] is not null or undefined.
In b = [] == true ? 1 : 2, it would return 1 if [] is true, but it's not, so it returns 2.
The first is an assignment and thus has to fall through to true (but DOESN'T equate anything). Equating empty to true will be false.
Because initialising an array with [] returns true and [] == true does not :-)