Can someone please explain Why does Boolean(Infinity) is true but Boolean(NaN) is false?
Infinity || true
expression gives Infinity.
`
NaN || true
` expression gives true.
EMCAScript's logical OR casts its arguments to booleans using ToBoolean, which behaves as follows for numbers:
The result is false if the argument is +0, −0, or NaN; otherwise the result is true.
Thus, NaN becomes false, and Infinity becomes true. We sometimes refer to values as "truthy" or "falsy" depending on whether ToBoolean coerces them to true or false.
If you look at the spec for logical OR, the operator returns either the original lval or rval (left/right value), not its coerced boolean value. This is why (Infinity || true) == Infinity: the value of ToBoolean(lval) is true, so the expression returns the original lval.
This is a combination of two things: How "truthiness" is tested, and the curiously-powerful || operator.
Truthiness: When using boolean logic in JavaScript, the arguments are converted to booleans. How this happens is covered in the spec, Section 9.2, which says amongst other things that when converting a value to a boolean from a number:
The result is false if the argument is +0, −0, or NaN; otherwise the result is true.
Curiously-powerful || operator: JavaScript's || operator does not evalute to true or false. It evaluates to its left-hand argument if that argument is "truthy," or its right-hand argument otherwise. So 1 || 0 is 1, not true; and false || 0 is 0 (even though 0 is falsey). So for the same reason, Infinity || true is Infinity, not true.
This feature of || is incredibly powerful. You can do things like this, for instance:
someElement.innerHTML = name || "(name missing)";
...and if name is not undefined, null, 0, "", false, or NaN, innerHTML gets set to name; if it is one of those values, it gets set to "(name missing").
Similarly, you can have default objects:
var obj = someOptionalObject || {};
The uses are many and varied. You do have to be careful, though, that you don't unintentionally weed out valid falsey values like 0 when you're defaulting things in this way. :-)
A chain of || operators strung together (a || b || c) returns the first truthy argument in the chain, or the last argument if none of them are truthy.
The && operator does something quite similar: It returns its first argument if that argument is falsey, or its right argument otherwise. So 0 && 1 is 0, not false. 2 && 1 is 1, because 2 is not falsey. And chains of them return the first falsey arg, or the last arg, which is handy when you need to get a property from a nested object:
var prop = obj && obj.subobj && obj.subobj.property || defaultValue;
...returns obj if it's falsey, or obj.subobj if it's falsey, or obj.subobj.property if neither of the first two is falsey. Then the result of that || defaultValue gives you either the property, or the default.
It is because NaN stands for "not a number", practically speaking it has no value. In certain languages (like Java, AS3) this is the default value of an uninitialized floating point variable. However Infinity (no matter positive/negative) is a valid representation of an unreachable value.
When you convert their numeric value to boolean, it has come into effect.
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 am unable to understand this.
Following is expression uses OR operator
var subCond1 = adj.getData('relationEnabled') == 'true' || adj.getData('unhideIfHidden') || adj.getData('hlFixed') == 'true';
I am expecting that since it is OR operation, it should return boolean true/false, but instead I get string 'false' as a result.
Can anyone explain this please?
Yup, that's just one of the features of || in JavaScript, and it's deliberate. It doesn't return a boolean (necessarily), it works like this: It evaluates the left-hand operand and if that operand is truthy, it returns it; otherwise, it evalutes and returns the right-hand operand.
So what's "truthy"? Anything that isn't "falsy". :-) The falsy values are 0, "", null, undefined, NaN, and of course, false. Anything else is truthy.
If you need a boolean, just !! the result:
var subCond1 = !!(adj.getData('relationEnabled') == 'true' || adj.getData('unhideIfHidden') || adj.getData('hlFixed') == 'true');
...but you frequently don't need to bother.
This behavior of || is really useful, particularly (I find) when dealing with object references that may be null, when you want to provide a default:
var obj = thisMayBeNull || {};
Now, obj will be thisMayBeNull if it's truthy (non-null object references are truthy), or {} if thisMayBeNull is falsy.
More in this article on my blog: JavaScript's Curiously-Powerful OR Operator (||)
Just to round things out: The && operator has a similar behavior: It evaluates the left-hand operand and, if it's falsy, returns it; otherwise it evaluates and returns the right-hand operator. This is useful if you want an object property from a variable which may be null:
var value = obj && obj.property;
value will be the value of obj if obj is falsy (for instance, null), or the value of obj.property if obj is truthy.
Javascript returns the first operand that has a truthy value, whatever that truthy value is or the value of the last operand if none before are truthy. That is a designed feature of Javascript (yes it is different than other languages).
You can turn that into a boolean by comparing to see if it is == true if you want or it is sometimes done with !!.
What is the explanation for behavior of the "||" operator (logical OR), when using it with false and undefined on both sides in JavaScript?
1)
> false || undefined
undefined
2)
> undefined || false
false
The logical OR operator isn't commutative like +, *, etc. It returns the first expression which can be converted into true. (Source Mozilla Doc)
In false || undefined, false can't be converted to true by definition (since it's the opposite), so it returns the second operand (undefined)
In undefined || false, undefined is a value, but considered as false in Javascript, so the logical operator evaluate the second operand and returns false (because both operands are false).
According to Logical Operators in Mozilla Docs:
Logical OR (||)
expr1 || expr2
Returns 'expr1' if it can be converted to true; otherwise, returns 'expr2.
1) in case false || undefined: false(expr1) can not be converted to true, so undefined(expr2) is returned
2) in case undefined || false: undefined(expr1) can not be converted to true, so
false(expr2) is returned
This question is not related particularly to just false and undefined but, to any of the Falsy Values in Javascript. Note that there are a total of six falsy values in Javascript:
false.
0 (zero)
'' or "" (an empty string)
null
undefined
NaN
When you run the logical OR operation between two Falsy Values, say <left value> || <right value> in JS, it always returns the value on the right side of the OR operator. Reason being that the OR operator, as per its implementation in ECMAScript Engines, in general returns the left value if it can be coerced to true. But, if the value on the left side of the operator cannot be coerced to true, the right value is always returned no matter what the value on the right is, instead of getting coerced as one might expect.
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).
This question already has answers here:
Why don't logical operators (&& and ||) always return a boolean result?
(9 answers)
Closed 8 years ago.
edit :
Quote removed. is not related to the question.
Question
How come does it always (when all are truthy) takes the last value ?
Examples :
f= 1 && 2 && 3 //3
f= 'k' && 'd' && 's' //'s'
p.s. : I've noticed that when investigating the pub/sub using $.callbacks
Operator && acts as an if-statement. The short-circuit occurs only if a value is false. Otherwise, it keeps evaluating statements.
When you write a && b it means: a ? b : a.
Similarly, a || b means: a ? a : b.
Edit: author has clarified the question significantly.
JavaScript logical AND operator return the left operand if it is falsy or else it returns the right operand.
Let us take a look at the table of logical truth:
A B A && B
true true true
true false false
false true false
false false false
As you can see, if A is false, we can return it:
A A && B
false false
false false
If A is not false, we can return B:
B A && B
true true
false false
This is a minor optimization, which leads to interesting sideeffects when used with weak typing, such as inline if:
var result = callback && callback()
// Generally equivalent to a simple if:
if (callback)
result = callback();
else
result = null;
Also using default options:
name = name || 'John';
// Generally equivalent to a simple if:
if (!name)
name = 'John';
As to why it happens, well, because these operators are defined like that in ECMA-262.
So how come does it always (when all are truthy) takes the last value ?
Because it can't short-circuit if the leading values are truthy, because it's an "AND" operator, and all operands must be truthy to satisfy the condition.
Re your comment below:
yes but why does it returns the last value ?
Because it's useful. :-) In the very first version of JavaScript from Netscape, it just returned true if the overall expression was true and false if not, but almost immediately they realized that it's much more useful if it returns the final operand.
For instance, you can do this:
var value = obj && obj.value;
...which will set value to be either a falsey value (if obj is falsey) or obj.value (if obj is not falsey). Importantly, it won't throw an error if obj is falsey. Very handy for guarding if you don't know for sure that obj is set. You don't have to stop at one level, either:
var value = obj && obj.sub && obj.sub.value;
value will either be falsey, or the value of obj.sub.value if both obj and obj.sub are truthy (e.g., because we seem to be using them as objects, they're object instances rather than null or undefined).
|| does the same sort of thing: It returns its first truthy operand.
More: JavaScript's Curiously Powerful OR Operator (||)
Because if first one is truthy, then it should go on and check second operand till the last one. If you would go with 1 || 2 || 3 instead it will return 1.
&& is a logical operator. This tests whether a value is truthy or falsy. This linked article explains that falsy values are equal to undefined, null, NaN, 0, "" and false.
Logical expressions are checked from left to right. If any part of the expression is evaluated t be falsy, the remainder of the expression will not be evaluated. In your examples, the value is always truthy. Here we can break down your first expression:
f = 1 && 2 && 3;
f = 1 /* Okay, 1 is a truthy value, lets continue... */
f = 2 /* Still truthy, let's continue... */
f = 3 /* Still truthy, we've reached the end of the expression, f = 3. */
If any of the values before 3 were falsy, the expression would have ended. To show this in action, simply redeclare your variable as:
f = 1 && 2 && 0 && 3;
Here 0 is a falsy value (as mentioned above). The execution of your expression here will end at 0:
f = 1 /* Okay, 1 is a truthy value, lets continue... */
f = 2 /* Still truthy, let's continue... */
f = 0 /* Hey, this is falsy, lets stop here, f = 0. */
f = 3 /* We never get here as the expression has ended */
Here f ends up being 0.
In your jQuery.Topic() example, && is used to ensure that id actually exists:
topic = id && topics[id]
We can break this down in the same way:
/* Assume this is your topics array: */
topics = ["", "My First Topic", "My Second Topic"];
/* If we pass in the value 1 as "jQuery.Topic(1)": */
topic = id && topics[id]
topic = 1 /* This is truthy, let's continue... */
topic = topics[1] /* topics[1] === "My First Topic" */
/* Now lets assume we pass in nothing as "jQuery.Topic()": */
topic = id && topics[id]
topic = null /* This is falsy, let's stop here, topic = null. */
The following if statement will only work if topic is truthy. In the first example, this is the case as topic has a value which is set to a string which isn't empty. In the second example, topic is null which is falsy.
The ECMAScript Standard states 12.11.2 Runtime Semantics: Evaluation:
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
1. Let lref be the result of evaluating LogicalANDExpression.
2. Let lval be GetValue(lref).
3. Let lbool be ToBoolean(lval).
4. ReturnIfAbrupt(lbool).
5. If lbool is false, return lval.
6. Let rref be the result of evaluating BitwiseORExpression.
7. Return GetValue(rref).
That is, first we check whether the first operand is evaluated to be a "falsy" value (null, false, 0). If it is, then the first operand is returned.
If, however, it's "thruthy", then the same process is repeated for the second operand and if it is evaluated as a truthy value, then the original value is returned (7. Return GetValue(rref)).
Short-circuit evaluation and returning the second expression instead of a bool are quite useful features.
The && operator evaluates the left operand and if it's truthy evaluates the right operand. Similarly the || operator evaluates the left operand and if it's falsy evaluates the right operand.
This allows to write things like
draw_element(color || "#F00");
with the meaning of using color unless if it's not specified (e.g. color is null, undefined or "") and in that case the default value is used.
You can even use things like
draw_element(color || pick_new_color());
and the function pick_new_color() will be called only if a color is not specified.
A very common use of && instead is to avoid errors, e.g:
if (x && x.constructor == Array) {
...
}
because if x is null or undefined you cannot access attributes (an exception would be raised if you try). The fact that && returns the first result if it's falsy instead of just false is not so useful indeed. Your code example does it, but it's not something you will find often in Javascript programs.
To recap: && and || are short-circuiting (i.e. they don't even evaluate the second operand if the result is known after evaluating the first) and this is very useful. They also return the falsy/truthy value itself instead of a bool, and this is very useful for || (not so much useful for &&).