If we alert(null==undefined) it outputs to true.
What is the logical reason for this.
Is this something that is hard coded in javascript or is there an explanation for this.
The language specification explicitly says:
If x is null and y is undefined, return true
I'm not aware of any records of the language design process that explain the reasoning for that decision, but == has rules for handling different types, and "null" and "undefined" are both things that mean "nothing", so having them be equal makes intuitive sense.
(If you don't want type fiddling, use === instead).
Using the double-equal operator forces Javascript to do type coercion.
In other words, when you do x == y, if x and y are not of the same type, JavaScript will cast one value to another before comparing, like if string and number are compared, the string is always cast into a number and then compared
For this reason, many comparisons of mixed types in JavaScript can result in results that may be unexpected or counter-intuitive.
If you want to do comparisons in JavaScript, it is usually a better idea to use the triple-equal operator === rather than double-equal. This does not do a type coercion; instead if the types are different, it returns false. This is more usually what you need.
You should only use double-equal if you are absolutely certain that you need it.
For the same reason that 0 == "0" - javascript is loosely typed - if something can be converted to something else then it will be unless you use ===
alert(null===undefined);
Will give you false.
As for why these particular conversions happen - the answer is quite simply "the spec says that is what should happen". There doesn't need to be a reason other than "because it says so" for why programming language behave in certain ways.
Edit: Slightly better answer - in Javascript, certain objects/values are 'truthy' or 'falsey' when converted to a boolean. 0 (integer zero), "0" (character zero in a string), "" (empty string) are all false. If there isn't a better comparison to use then the boolean operation applies.
This is why "0" is not equal to an empty string, but both "0" and "" are both equal to false.
we know,
If x is null and y is undefined, return true
undefined == null => true, reason might be both are converted to boolean, as we know javascript performs the type conversion. so that will be resulting the null and undefined converted to false and false == false is true
A better explanation...
In the case of "==" or Loose Equality Operator, if one of the operands is null or undefined and the other is null or undefined, always return true. Otherwise return false. Unlike what other posters falsely state, these are not converted or coerced into new types when using equality operators, but simply follow the rule above.
// TRUE - loose equality operator says use the null vs. undefined rule above which equates them
console.log(null == undefined);
// FALSE - strict equality operator says these are not of the same type, so always return false
console.log(null === undefined);
The == comparison operator doesn't check the types. null and undefined both return false. That's why your code is actually checking if false is equal to false.
> null == undefined;
< true
> false == false
< true
However their types are not equal.
> typeof undefined;
< "undefined"
> typeof null;
< "object"
Because of that, the next statement will return false, as the === comparison operator checks both the types and their value.
> undefined === null;
< false
Related
What are the values in JavaScript that are 'falsey', meaning that they evaluate as false in expressions like if(value), value ? and !value?
There are some discussions of the purpose of falsey values on Stack Overflow already, but no exhaustive complete answer listing what all the falsey values are.
I couldn't find any complete list on MDN JavaScript Reference, and I was surprised to find that the top results when looking for a complete, authoritative list of falsey values in JavaScript were blog articles, some of which had obvious omissions (for example, NaN), and none of which had a format like Stack Overflow's where comments or alternative answers could be added to point out quirks, surprises, omissions, mistakes or caveats. So, it seemed to make sense to make one.
Falsey values in JavaScript
false
Zero of Number type: 0 and also -0, 0.0, and hex form 0x0 (thanks RBT)
Zero of BigInt type: 0n and 0x0n (new in 2020, thanks GetMeARemoteJob)
"", '' and `` - strings of length 0
null
undefined
NaN
document.all (in HTML browsers only)
This is a weird one. document.all is a falsey object, with typeof as undefined. It was a Microsoft-proprietory function in IE before IE11, and was added to the HTML spec as a "willful violation of the JavaScript specification" so that sites written for IE wouldn't break on trying to access, for example, document.all.something; it's falsy because if (document.all) used to be a popular way to detect IE, before conditional comments. See Why is document.all falsy? for details
"Falsey" simply means that JavaScript's internal ToBoolean function returns false. ToBoolean underlies !value, value ? ... : ...; and if (value). Here's its official specification (2020 working draft) (the only changes since the very first ECMAscript specification in 1997 are the addition of ES6's Symbols, which are always truthy, and BigInt, mentioned above:
Argument type
Result
Undefined
Return false.
Null
Return false.
Boolean
Return argument.
Number
If argument is +0, -0, or NaN, return false; otherwise return true.
String
If argument is the empty String (its length is zero), return false; otherwise return true.
BigInt
If argument is 0n, return false; otherwise return true.
Symbol
Return true.
Object
Return true.
Comparisons with == (loose equality)
It's worth talking about falsy values' loose comparisons with ==, which uses ToNumber() and can cause some confusion due to the underlying differences. They effectively form three groups:
false, 0, -0, "", '' all match each other with ==
e.g. false == "", '' == 0 and therefore 4/2 - 2 == 'some string'.slice(11);
null, undefined match with ==
e.g. null == undefined but undefined != false
It's also worth mentioning that while typeof null returns 'object', null is not an object, this is a longstanding bug/quirk that was not fixed in order to maintain compatibility. It's not a true object, and objects are truthy (except for that "wilful violation" document.all when Javascript is implemented in HTML)
NaN doesn't match anything, with == or ===, not even itself
e.g. NaN != NaN, NaN !== NaN, NaN != false, NaN != null
With "strict equality" (===), there are no such groupings. Only false === false.
This is one of the reasons why many developers and many style guides (e.g. standardjs) prefer === and almost never use ==.
Truthy values that actually == false
"Truthy" simply means that JavaScript's internal ToBoolean function returns true. A quirk of Javascript to be aware of (and another good reason to prefer === over ==): it is possible for a value to be truthy (ToBoolean returns true), but also == false.
You might think if (value && value == false) alert('Huh?') is a logical impossibility that couldn't happen, but it will, for:
"0" and '0' - they're non-empty strings, which are truthy, but Javascript's == matches numbers with equivalent strings (e.g. 42 == "42"). Since 0 == false, if "0" == 0, "0" == false.
new Number(0) and new Boolean(false) - they're objects, which are truthy, but == sees their values, which == false.
0 .toExponential(); - an object with a numerical value equivalent to 0
Any similar constructions that give you a false-equaling value wrapped in a type that is truthy
[], [[]] and [0] (thanks cloudfeet for the JavaScript Equality Table link)
Some more truthy values
These are just a few values that some people might expect to be falsey, but are actually truthy.
-1 and all non-zero negative numbers
' ', " ", "false", 'null'... all non-empty strings, including strings that are just whitespace
Anything from typeof, which always returns a non-empty string, for example:
typeof null (returns a string 'object' due to a longstanding bug/quirk)
typeof undefined (returns a string 'undefined')
Any object (except that "wilful violation" document.all in browsers). Remember that null isn't really an object, despite typeof suggesting otherwise. Examples:
{}
[]
function(){} or () => {} (any function, including empty functions)
Error and any instance of Error
Any regular expression
Anything created with new (including new Number(0) and new Boolean(false))
Any Symbol
true, 1, "1" and [1] return true when compared to each other with ==.
Don't forget about the non-empty string "false" which evaluates to true
Just to add to #user568458's list of falsy values:
In addition to integer number 0, the decimal number 0.0, 0.00 or any such zeroish number is also a falsy value.
var myNum = 0.0;
if(myNum){
console.log('I am a truthy value');
}
else {
console.log('I am a falsy value');
}
Above code snippet prints I am a falsy value
Similarly hex representation of the number 0 is also a falsy value as shown in below code snippet:
var myNum = 0x0; //hex representation of 0
if(myNum){
console.log('I am a truthy value');
}
else {
console.log('I am a falsy value');
}
Above code snippet again prints I am a falsy value.
Addition to the topic, as of ES2020 we have a new value which is falsy, it's BigInt zero (0n):
0n == false // true
-0n == false // true
0n === false // false
-0n === false // false
So with this, we now have 7 "falsy" values in total (not including document.all as mentioned by user above since it's part of DOM and not JS).
I've encountered something which seems inconsistent on the part of the interpreter, though I know it probably makes sense and I just don't understand it. It has to do with evaluating the equality of a truthy/falsy values and Booleans.
Example 1:
if (document.getElementById('header')) {
//run code here
}
If the element with an id of 'header' is found in the document, the condition is true because the presence of an object is considered truthy.
Example 2:
if (document.getElementById('header) == true) {
// run code here
}
Presuppose the referenced element is found within the document. It was explained to me that this condition will evaluate to false because a truthy value does not equal a Boolean value of true.
This doesn't seem to make sense. The presence of the object is considered truthy due to type coercion, so therefore it should equal true even though the data types are different.
Consider the following:
(false == 0) // evaluates to true
(false === 0) // evaluates to false
This is a case where false equals 0 is true when you use the equals to operator. Because 0 is considered a falsy value, it is equal to the Boolean value of false. The values are the same and the data types are different.
To me, (document.getElementById('header') == true) and (false == 0) are the same thing. And yet, they both evaluate to something different.
Can someone please explain to me why this is the case? I've been reading different descriptions of this, but no one seems to explain it in-depth.
document.getElementById('header') returns a DOM object or null. So, in your second comparison (assuming it is resolving to an object), you're comparing:
if (obj == true)
A DOM object is not == to true.
To see why, you have to go to the ECMAScript rules for automatic type conversion which you can see in the ECMAScript 5 specification here: http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3.
The operative rules when comparing an object == boolean are all the way down to rules 9 and 10.
If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
Return false.
Rule 9 is the first rule where Type(x) is Object and the two types are not the same, so it's the first one to check.
Since Type(y) is Boolean, it does not pass rule 9.
Thus, when it hasn't passed any rules 1-9, it evaluates to false.
When you do this comparison:
(false == 0) // evaluates to true
you're looking at rule #6 in the type conversion rules which will do:
ToNumber(false) == 0
which will resolve to:
0 == 0
which will be true.
For this one:
(false === 0)
Whenever you use ===, if the two types are different, then the result is immediately false so this evaluates to false. === requires type AND value to be the same so if the type is not the same, then it doesn't even attempt to compare the value. No type conversion is ever done with === which is one of the useful reasons to use it.
You should understand that the truthy and falsey rules apply to only a single check like this with no == or === in the comparison:
if (obj)
They do not apply when you are comparing x == y. For that, you have to refer to the type conversion rules in section 11.9.3 of the specification (linked above).
Presuppose the referenced element is found within the document. It was explained to me that this condition will evaluate to false because a truthy value does not equal a Boolean value of true.
You're right, it doesn't make sense because whoever explained that to you is wrong.
The presence of a DOM element will evaluate to true and if it doesn't exist, it will evaluate to false (with a double-equals vs. triple). If in the event they are using triple equals, you can simply try:
!!document.getElementById('someNodeId') and it will return a boolean value.
You can always try this in the console if you want to be sure.
!!document.getElementById('notify-container');
>> true
!!document.getElementById('non-existing-node-goes-here');
>> false
Edit: I didn't read the example clearly or the example was updated. Yeah, you're using double equal. The element is truthy, but it's not "true".
When the if() statement is executing, it's checking if there is a truthy value inside the parenthesis. The == operator is checking whether the two values are equal in nature. In JavaScript, true and false are == to 1 and 0, respectively; hence why you can type (4 + true) and get 5, or false*6 and get 0!
When you type something == true, you're really checking if something == 1.
If something isn't a boolean value it's not going to be the same as 1.
Perhaps an explanation of your postulate "The presence of the object is considered truthy due to type coercion, so therefore it should equal true."
If any truthy value is equal to true,
then any truthy value is equal to any truthy value (by transitive property, a=b,c=b, therefore a=c),
however, this would not hold true for all cases! ("blue" == "green", 5 == "six" simply because they are each non-false values. This would make the == fairly worthless!)
The conclusion does not follow, so therefore the postulate is invalid. In general, you should use === if you need to check if two things are truly the same thing.
Hopefully this clears things up!
What are the values in JavaScript that are 'falsey', meaning that they evaluate as false in expressions like if(value), value ? and !value?
There are some discussions of the purpose of falsey values on Stack Overflow already, but no exhaustive complete answer listing what all the falsey values are.
I couldn't find any complete list on MDN JavaScript Reference, and I was surprised to find that the top results when looking for a complete, authoritative list of falsey values in JavaScript were blog articles, some of which had obvious omissions (for example, NaN), and none of which had a format like Stack Overflow's where comments or alternative answers could be added to point out quirks, surprises, omissions, mistakes or caveats. So, it seemed to make sense to make one.
Falsey values in JavaScript
false
Zero of Number type: 0 and also -0, 0.0, and hex form 0x0 (thanks RBT)
Zero of BigInt type: 0n and 0x0n (new in 2020, thanks GetMeARemoteJob)
"", '' and `` - strings of length 0
null
undefined
NaN
document.all (in HTML browsers only)
This is a weird one. document.all is a falsey object, with typeof as undefined. It was a Microsoft-proprietory function in IE before IE11, and was added to the HTML spec as a "willful violation of the JavaScript specification" so that sites written for IE wouldn't break on trying to access, for example, document.all.something; it's falsy because if (document.all) used to be a popular way to detect IE, before conditional comments. See Why is document.all falsy? for details
"Falsey" simply means that JavaScript's internal ToBoolean function returns false. ToBoolean underlies !value, value ? ... : ...; and if (value). Here's its official specification (2020 working draft) (the only changes since the very first ECMAscript specification in 1997 are the addition of ES6's Symbols, which are always truthy, and BigInt, mentioned above:
Argument type
Result
Undefined
Return false.
Null
Return false.
Boolean
Return argument.
Number
If argument is +0, -0, or NaN, return false; otherwise return true.
String
If argument is the empty String (its length is zero), return false; otherwise return true.
BigInt
If argument is 0n, return false; otherwise return true.
Symbol
Return true.
Object
Return true.
Comparisons with == (loose equality)
It's worth talking about falsy values' loose comparisons with ==, which uses ToNumber() and can cause some confusion due to the underlying differences. They effectively form three groups:
false, 0, -0, "", '' all match each other with ==
e.g. false == "", '' == 0 and therefore 4/2 - 2 == 'some string'.slice(11);
null, undefined match with ==
e.g. null == undefined but undefined != false
It's also worth mentioning that while typeof null returns 'object', null is not an object, this is a longstanding bug/quirk that was not fixed in order to maintain compatibility. It's not a true object, and objects are truthy (except for that "wilful violation" document.all when Javascript is implemented in HTML)
NaN doesn't match anything, with == or ===, not even itself
e.g. NaN != NaN, NaN !== NaN, NaN != false, NaN != null
With "strict equality" (===), there are no such groupings. Only false === false.
This is one of the reasons why many developers and many style guides (e.g. standardjs) prefer === and almost never use ==.
Truthy values that actually == false
"Truthy" simply means that JavaScript's internal ToBoolean function returns true. A quirk of Javascript to be aware of (and another good reason to prefer === over ==): it is possible for a value to be truthy (ToBoolean returns true), but also == false.
You might think if (value && value == false) alert('Huh?') is a logical impossibility that couldn't happen, but it will, for:
"0" and '0' - they're non-empty strings, which are truthy, but Javascript's == matches numbers with equivalent strings (e.g. 42 == "42"). Since 0 == false, if "0" == 0, "0" == false.
new Number(0) and new Boolean(false) - they're objects, which are truthy, but == sees their values, which == false.
0 .toExponential(); - an object with a numerical value equivalent to 0
Any similar constructions that give you a false-equaling value wrapped in a type that is truthy
[], [[]] and [0] (thanks cloudfeet for the JavaScript Equality Table link)
Some more truthy values
These are just a few values that some people might expect to be falsey, but are actually truthy.
-1 and all non-zero negative numbers
' ', " ", "false", 'null'... all non-empty strings, including strings that are just whitespace
Anything from typeof, which always returns a non-empty string, for example:
typeof null (returns a string 'object' due to a longstanding bug/quirk)
typeof undefined (returns a string 'undefined')
Any object (except that "wilful violation" document.all in browsers). Remember that null isn't really an object, despite typeof suggesting otherwise. Examples:
{}
[]
function(){} or () => {} (any function, including empty functions)
Error and any instance of Error
Any regular expression
Anything created with new (including new Number(0) and new Boolean(false))
Any Symbol
true, 1, "1" and [1] return true when compared to each other with ==.
Don't forget about the non-empty string "false" which evaluates to true
Just to add to #user568458's list of falsy values:
In addition to integer number 0, the decimal number 0.0, 0.00 or any such zeroish number is also a falsy value.
var myNum = 0.0;
if(myNum){
console.log('I am a truthy value');
}
else {
console.log('I am a falsy value');
}
Above code snippet prints I am a falsy value
Similarly hex representation of the number 0 is also a falsy value as shown in below code snippet:
var myNum = 0x0; //hex representation of 0
if(myNum){
console.log('I am a truthy value');
}
else {
console.log('I am a falsy value');
}
Above code snippet again prints I am a falsy value.
Addition to the topic, as of ES2020 we have a new value which is falsy, it's BigInt zero (0n):
0n == false // true
-0n == false // true
0n === false // false
-0n === false // false
So with this, we now have 7 "falsy" values in total (not including document.all as mentioned by user above since it's part of DOM and not JS).
I was reading a good book on JavaScript.
It started with:
Boolean type take only two literal values: true and false. These are distinct from numeric values, so true is not equal to 1, and false is not equal to 0.
However, I observed following:
if(1==true)
document.write("oh!!! that's true"); //**this is displayed**
I know, that every type in JavaScript has a Boolean equivalent.
But then, what's the truth?
It's true that true and false don't represent any numerical values in Javascript.
In some languages (e.g. C, VB), the boolean values are defined as actual numerical values, so they are just different names for 1 and 0 (or -1 and 0).
In some other languages (e.g. Pascal, C#), there is a distinct boolean type that is not numerical. It's possible to convert between boolean values and numerical values, but it doesn't happen automatically.
Javascript falls in the category that has a distinct boolean type, but on the other hand Javascript is quite keen to convert values between different data types.
For example, eventhough a number is not a boolean, you can use a numeric value where a boolean value is expected. Using if (1) {...} works just as well as if (true) {...}.
When comparing values, like in your example, there is a difference between the == operator and the === operator. The == equality operator happily converts between types to find a match, so 1 == true evaluates to true because true is converted to 1. The === type equality operator doesn't do type conversions, so 1 === true evaluates to false because the values are of different types.
In JavaScript, == is pronounced "Probably Equals".
What I mean by that is that JavaScript will automatically convert the Boolean into an integer and then attempt to compare the two sides.
For real equality, use the === operator.
Try the strict equality comparison:
if(1 === true)
document.write("oh!!! that's true"); //**this is not displayed**
The == operator does conversion from one type to another, the === operator doesn't.
From the ECMAScript specification, Section 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(y) is Boolean, return the result of the comparison x == ToNumber(y).
Thus, in, if (1 == true), true gets coerced to a Number, i.e. Number(true), which results in the value of 1, yielding the final if (1 == 1) which is true.
if (0 == false) is the exact same logic, since Number(false) == 0.
This doesn't happen when you use the strict equals operator === instead:
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.
Ah, the dreaded loose comparison operator strikes again. Never use it. Always use strict comparison, === or !== instead.
Bonus fact: 0 == ''
When compare something with Boolean it works like following
Step 1: Convert boolean to Number Number(true) // 1 and Number(false) // 0
Step 2: Compare both sides
boolean == someting
-> Number(boolean) === someting
If compare 1 and 2 with true you will get the following results
true == 1
-> Number(true) === 1
-> 1 === 1
-> true
And
true == 2
-> Number(true) === 1
-> 1 === 2
-> false
Actually every object in javascript resolves to true if it has "a real value" as W3Cschools puts it. That means everything except "", NaN, undefined, null or 0.
Testing a number against a boolean with the == operator indeed is a tad weird, since the boolean gets converted into numerical 1 before comparing, which defies a little bit the logic behind the definition.
This gets even more confusing when you do something like this:
var fred = !!3; // will set fred to true
var joe = !!0; // will set joe to false
alert("fred = "+ fred + ", joe = "+ joe);
not everything in javascript makes a lot of sense ;)
Use === to equate the variables instead of ==.
== checks if the value of the variables is similar
=== checks if the value of the variables and the type of the variables are similar
Notice how
if(0===false) {
document.write("oh!!! that's true");
}
and
if(0==false) {
document.write("oh!!! that's true");
}
give different results
In a way, yes it is 1.
Try these examples in Chrome console:
> 2==true
false
> 1==true
true
> true + 1
2
> true + 2
3
> true + true
2
So, the answer is:
yes, as soon as you use true in any arithmetical context, it's treated as numeric 1, or as Bruce Lee would say, it becomes one. The same way, false is practically zero. But also,
no, if you ask Javascript what it thinks of true, it will say it's a boolean:
> typeof true
'boolean'
It's no surprise in a loosely typed language that sometimes things are not what they are but how you look at them. And if you add true to a string, it will not add 1 but "true" as a string, so at the end of the day, it's by no means equivalent to one. Let me end this with a horrible pun:
true is not a number - but it looks like one
with == you are essentially comparing whether a variable is falsey when comparing to false or truthey when comparing to true. If you use ===, it will compare the exact value of the variables so true will not === 1
I'm wondering what the core difference is between the conditional syntax below?
if (something) {
// do something
}
vs.
if (something == true) {
// do something
}
Are there any differences?
Edit: I apologize. I made a typo when the question was asked. I did not mean to put a triple equals sign. I know that triple equals is a strict operator. I was meaning to ask if '==' is the equivalent of if (something).
The difference is that in if(something), something is evaluated as boolean. It is basically
if(ToBoolean(something))
where ToBoolean is an internal function that is called to convert the argument to a boolean value. You can simulate ToBoolean with a double negation: !!something.
In the second case, both operands are (eventually) converted to numbers first, so you end up with
if(ToNumber(something) == ToNumber(true))
which can lead to very different results. Again, ToNumber is an internal function. It can be simulated (to some degree) using the unary plus operator: +something == +true. In the actual algorithm, something is first passed ToPrimitive if something is an object.
Example:
Assume that
var something = '0'; // or any other number (not 0) / numeric string != 1
if(something) will be true, since '0' is a non-empty string.
if(something == true) will be false, since ToNumber('0') is 0, ToNumber(true) is 1 and 0 == 1 is false.
EDIT: Below only holds true for the original question, in which the === operator was used.
The first one will execute the body of the if-statement if something is "truthy" while the second will only execute it if it is equal in type and value to true.
So, what is "truthy"? To understand that, you need to know what is its opposite: falsey. All values in JavaScript will be coerced into a Boolean value if placed in a conditional expression. Here's a list of falsey values:
false
0 (zero)
"" (empty string)
null
undefined
NaN
All other values are truthy, though I've probably missed some obscure corner case that someone will point out in the comments.
Here's my answer to the updated question:
The conditional if (something) and if (something == true) are equivalent, though the second is redundant. something will be type coerced in the same way in either case. This is wrong. See Felix Kling's answer.
if(something) is equivalent to if(someting == true).
The == operator checks for equality while === checks for sameness. In this case, any truthy value will cause the condition to be met for the first one, but only true will cause the condition to be met for the second one.
EDIT: Felix Kling's answer is correct. Please reference that instead.
Now that the question has changed from === to ==, no, there is no practical difference.
There are a couple ways to look at it. The first example evaluates to see if "something" has a true-like or positive value. So as long as it is not 0, negative, null, or empty it should evaluate the contents of that if statement.
In your second statement you are testing to see if "something" is the equivalent of boolean true. Another words "TRUE" or 1. You could also do a "===" comparison so that it has to be identical to what your comparing it to. So in this case if you did something === true then "something" would have to be boolean true, the value of 1 would not suffice.
There is no difference between the two conditions thing == true and just thing.
There is a large difference between thing === true and just thing, however.
In javascript, values are coerced to a boolean when they are put in a condition. This means all values of all types must be able to be coerced to either true or false. A value that coerces to true is generally called "truthy", and a value that coerces to false is called "falsey".
The "falsey" values are as follows:
NaN (not a number)
'' (empty string)
undefined
null
0 (numeric 0)
Everything else evaluates to true when coerced. This jsFiddle will help you keep track of what is "truthy" and what is "falsey".
The identity operator (===) does NOT perform any type coercion: if the types are different, the comparison immediately fails.