String coercion into boolean - javascript

Boolean("a")
returns true in the Browser console.
So why
"a" == true
returns false?

How the == operator functions on certain types is defined in the ECMAScript specifications. It is as followed:
7.2.13 Abstract Equality Comparison
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.
Now we can apply them to this the cases above. Which first converts the boolean into a number and then attempts to convert the string into a number (which is parsed as NaN):
"a" == true
// Case 7 (true --> 1)
// =>"a" == 1
// Case 5 ("a" --> NaN)
// => NaN == 1
=> false

You need to see how Javascripts works.
"a" is a string.
true is a boolean.
So "a" is not equal to true.
Doing Boolean("a"), is like to ask "Is "a" ?". This bizarre question will answer true if what you put in (so here "a") is [implicitly something not null or empty].
You shouldn't use this Boolean function in this context, the result will never be what you think (Boolean("false") will return true for example)
See here for more information: https://stackoverflow.com/a/264037/6532640

// Boolean("a") is equal to asking if "a" == "a" so it will return true
console.log(Boolean("a"));
// "a" == true can't return true, because a string and a boolean can't be equal
console.log("a" == true);
// for the same reason this will return false too
console.log("true" == true);
// and this will return true
console.log("true" == true.toString());
//-----------------------------------------
// If we talk about numbers, there are different rules.
// In javascript you will be able to convert a string with
// numbers to a number and vice versa
// this is why "1" is equal to 1
console.log("1" == 1);
// considering the interest in trying to use every kind of
// variable in var, they described some basical rules
// for example adding a number to a string will work
// like every language
// this is why here you will obtain "11" as result
var one = "1";
console.log(one+1);
// in this case - doesn't work with strings, so our var one
// will be considered as an integer and the result will be 1
var one = "1";
console.log(one-1+1);

Related

how to do you prove that boolean datatypes are converted to numbers when using the == operator in javaScript [duplicate]

I was wondering a few things about coercion.
When you do:
1 == true // true
Which one is coerced into which one ? is it the left one or the right one ?
When you do
undefined == null // true
How does it work exactly ?
In which order does it try to convert it ?
By instance:
1) String(undefined) == String(null) // false
2) Number(undefined) == Number(null) // false
3) Boolean(undefined) == Boolean(null) // true
Does it first try to coerce the left side operand ? then the right ? then both ?
EDIT:
As explained in the comments:
"not a duplicate. While both questions are about type coercion, this one asks which operand get coerced into the other. The other one is about the source of truth when evaluating the coerced types"
The process is described at 7.2.12 Abstract Equality Comparison:
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, 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.
So rather than coercing one side and then the other, or something like that, it's more that the interpreter goes through that list above until it finds a matching condition, and executes the resulting command, which may involve coercing only the left side, or only the right side (and, rarely, both, in case a recursive command is reached, such as with true == '1', which will fulfill condition 8, turn into 1 == '1', fulfilling condition 6 and turning into 1 == 1, fulfilling condition 3 and resolving to true)

Coercion in JavaScript

I was wondering a few things about coercion.
When you do:
1 == true // true
Which one is coerced into which one ? is it the left one or the right one ?
When you do
undefined == null // true
How does it work exactly ?
In which order does it try to convert it ?
By instance:
1) String(undefined) == String(null) // false
2) Number(undefined) == Number(null) // false
3) Boolean(undefined) == Boolean(null) // true
Does it first try to coerce the left side operand ? then the right ? then both ?
EDIT:
As explained in the comments:
"not a duplicate. While both questions are about type coercion, this one asks which operand get coerced into the other. The other one is about the source of truth when evaluating the coerced types"
The process is described at 7.2.12 Abstract Equality Comparison:
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, 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.
So rather than coercing one side and then the other, or something like that, it's more that the interpreter goes through that list above until it finds a matching condition, and executes the resulting command, which may involve coercing only the left side, or only the right side (and, rarely, both, in case a recursive command is reached, such as with true == '1', which will fulfill condition 8, turn into 1 == '1', fulfilling condition 6 and turning into 1 == 1, fulfilling condition 3 and resolving to true)

Why (!a) and (a == false) are not equal?

Talk is cheap, I will show my code.
var a; // a = undefined
if(a == false){ // As I typed == not ===, a needs to be translated to boolean (undefined == false) but it doesn't
return false;
}
else {
return true;
}
// true
This returns true but I was sure that it would return false because undefined is the same as false when I'm using double equal.
Things came strange when I tried to use
if(!a){..} else {..};
// false
Here I got my false but till this moment I thought (!a) and (a == false) are absolutely equals.
The short answer:
!a converts a value to a Boolean.
a == false compares a value to a Boolean.
These are two different operations.
!a is equivalent to Boolean(a) ? false : true. Boolean(a) returns false if a is
undefined
null
0
''
NaN
false
In every other case it returns true.
What happens in a == false is a bit more evolved, but not that complicated. The most important thing that happens is that false is converted to a number, so you are actually comparing a == 0. But undefined is treated in a special way in the comparison algorithm. It's not converted to any other type, so the algorithm simply returns false.
I wrote the following interactive tool for a JavaScript course which shows you which steps of the algorithm are performed when comparing two values:
Similar questions:
In JavaScript, why is "0" equal to false, but when tested by 'if' it is not false by itself?
Why does ('0' ? 'a' : 'b') behave different than ('0' == true ? 'a' : 'b')
JavaScript: What is the difference between `if (!x)` and `if (x == null)`?
Why "" == "0" is false in javascript?
The only correct answer is "that's the way it is". The source of your confusion is a feature of JavaScript called type coercion and different types of equality comprisons (==, === in JavaScript).
There's an interesting table which tells you which comparisons will result to true on JavaScript Equality Table.
The only two values which will give true when ==-compared with null are null and undefined.
In other words, x == null will be true if and only if x is null or undefined.
You had a false assumption. x == false does not coerect x to boolean. In fact, == has it's own equality table.
If you don't believe random blogposts, here is the spec:
7.2.12 Abstract Equality Comparison
The comparison x == y, where x and y are values, produces true or
false. Such a comparison is performed as follows:
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.
So for undefined == false: first we hit #9, and then #12, which evaluates to false.
(!a) and (a == false) are absolutely equals.
you use two different operators and assume they are absolutely equals - never do this, there is a reason 2 different operators exists instead of 1.
Now, think of NaN (as one example, others may apply). By definition NaN is a falsy value but not false value, so:
if(!NaN) {} // this will execute
if(NaN == false) {} // this will not execute
Why do you think this happens?
Because == operator does type coercion per type/value, thus NaN doesn't coerce to false, while others, like 0 may, but both will be considered falsy and converted to true using !
Summed:
operator ! uses a defined set of falsy values (false,0, '' or "" (empty string), null, undefined, NaN) all else is truthy
operator == uses per type conversions not regarding if the original value is considered falsy, so after being converted, it may well be truthy

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