This question already has answers here:
Why NaN is greater than any number in JavaScript? [duplicate]
(2 answers)
Closed 4 years ago.
I am trying to make some conditional statements while trying to solve a coding challenge. I have kept track of all the occurrences of letters of two strings in different objects. When I try to compare them by their counts if the count is undefined in the other object it evaluates to false even though the first value is truthy.
However;
1 > Boolean(undefined) evaluates to true. However 1 > undefined evaluates to false. Is there reason why the behavior is so ?
Javascript does a lot of funky casting when you compare things together that usually shouldn't be comparable.
1>undefined casts undefined to a NaN, and you can't compare a number to a Not a Number so any comparison will return false >,<,== etc
When you do 1>Boolean(undefined) undefined is cast to its boolean equivalent false, then when it's compared it will be cast to a 0, you can confirm this by doing Number(Boolean(undefined)) and since 1 is bigger than 0 it returns true.
In order to use the comparison operator >, both operands must be numeric. 1 already is, so Boolean(undefined) (which evaluates to false by the way) must be converted to a number. When it is, you get 0.
// First, convert undefined to a Boolean
let bool = Boolean(undefined)
console.log(bool);
// Then convert that to a number
let num = Number(bool);
console.log(num);
So, 1 > 0 is true.
Things to understand:
JavaScript is a "loosely" or "weakly" typed language. This means that data can, and often is, implicitly converted (coerced) into a different type category.
All data can be classified as "truthy" or "falsy", which means that if converted to a Boolean, would it convert to true or false. Things like null, undefined, "", 0, false, and NaN are all "falsy". And false in JavaScript (and most other languages) converts to the number 0, while true usually converts to 1.
Related
This question already has answers here:
Why does [NaN].includes(NaN) return true in JavaScript?
(5 answers)
Closed 24 days ago.
I'm learning about includes() feature, and I found this code
[NaN].includes(NaN) //True
But
NaN === NaN // False
Why this is posible?
Using equality NaN === NaN and using includes [NaN].includes(NaN) are basically asking two different questions:
Equality - are this things that have the same name are actually equal?
NaN is an amorphic entity, which describes the concept of not being a numeric value, and doesn't actually have a value you can compare. Equality uses the Strict Equality Comparison, and defines that a comparison x === y with NaN on any side of the equation is always false:
a. If x is NaN, return false.
b. If y is NaN, return false.
Includes - do I have something with that "name" in the array?
However, to search for a NaN in an array, and to keep the to Array#includes signature of passing only one param, and not a callback, we need a way to "name" what we are searching for. To make that possible, ccording to the Array#includes definition in the ECMAScript 2016 (ECMA-262) docs:
The includes method intentionally differs from the similar indexOf
method in two ways. First, it uses the SameValueZero algorithm,
instead of Strict Equality Comparison, allowing it to detect NaN
array elements. Second, it does not skip missing array elements,
instead treating them as undefined.
The definition of SameValueZero(x, y) states that when comparing:
If x is NaN and y is NaN, return true.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN
Unlike all other possible values in JavaScript, it is not possible to rely on the equality operators (== and ===) to determine whether a value is NaN or not, because both NaN == NaN and NaN === NaN evaluate to false. Hence, the necessity of an isNaN function.
[ NaN ].includes(NaN) what this does is to check if NaN is in the [ ].
NaN === NaN and NaN == NaN will still return the same value which is false. What you just have to know is that the includes methods checks if a value is the array it is been called on. Behind the hood i think the includes Array method does it's checks using typeof()
typeof(NaN) // number
[ NaN ].includes(NaN) // true
typeof("1") // string
[ 1 ].includes("1") // false
typeof(1) // number
[ 1 ].includes(1) // true
this is according to the SameValueZero Algorithm that the includes method uses. Internally it checks the type of the value
This question already has answers here:
All falsey values in JavaScript
(4 answers)
Closed 7 years ago.
This is something that I've always wondered. According to MDN, in JavaScript "The if statement executes a statement if a specified condition is true". So then why does this pass the statement?
var a = 7;
if( a ) {
alert('true');
} else {
alert('false');
}
The variable is neither true nor false, so why does it alert "true" instead of just skipping the entire if statement?
"is true" means "an expression that evaluates to a true value" not "is exactly equal to the boolean object true".
The formal language can be found in the specification.
Let exprRef be the result of evaluating Expression. If
ToBoolean(GetValue(exprRef)) is true, then Return the result of
evaluating the first Statement. Else, Return the result of
evaluating the second Statement.
In Javascript following values are always falsy:
false
0 (zero)
"" (empty string)
null
undefined
NaN (a special Number value meaning Not-a-Number!)
All other values are truthy, including "0" (zero in quotes), "false" (false in quotes), empty functions, empty arrays, and empty objects.
If you want to compare with true without type conversion try a === true.
In JavaScript if(var) evaluates not just for boolean, but also for defined/initialized or non defined variables.
For example, if a var is undefined or null in that case if evaluates them to false
As stated by other before, it's performing a boolean test on the variable.
Boolean values are binary; that's to say, the only possible values are 0 and 1, where true = 1, and false = 0.
The value you hard-coded into the if-statement is 7 = 0111, and all it takes is one of those numbers being a '1' to make it pass the test.
It work the same way with letters, except the if statement will convert letters from ASCII to binary: "A" = 0100 0001 (registered as 65 in ASCII. http://www.asciitable.com/) On the other hand, no input will return a false statement.
In a computer, everything is a number. Boolean too, and usually are just one bit: 0 or 1.
But computer use more than one bit to store data, so Boolean are more than 0 or 1, but also 255, 42, or 25, while still having to pass a simple test.
So by convention, 0 is false, and any other value is true.
This question already has answers here:
Why does ++[[]][+[]]+[+[]] return the string "10"?
(10 answers)
Closed 8 years ago.
Can anyone help me with this JavaScript expression?
+[[+!![]]+[+![]]+[+!![]]+[-~!![]+-~!![]-~!![]]+[-~!![]]+[+![]]+[+!![]]+[-~!![]+-~!![]]]
A friend sent it to me and asked me to copy and paste it in the browser console.
This is the result:
10162014
If anyone could explain this to me or at least point me to right references please. Thanks!
First break out your code to this: !![] which returns true (!! is to convert to boolean) and now + converts to number so +!![] returns 1.
![] converts to false so +![] returns 0.
~[] returns -1 and ~![] also returns -1.
~!![] returns -2.
Now, -~!![] returns 2 and -~![] returns 1.
So, combining them all returns 10162014.
All about you to know is ~, !, +, & -
![] = false; # as an expression, it's false due to the ! operatory
[] = true; # as an expression, it's defined, so it's true
+!![] = 1; because +true = 1;
+![] = 1; because +true = 0, because using a + operator in JS converts the boolean to an integer ref
So what he's done is basically constructed a numerical value using boolean to integer conversion, and some grouping.
[+!![]]+[+![]]+[+!![]]: [] is an empty array, which is truthy. ![] is thus false, !![] is true. +true forces it to a number, as 1. Similarly for +![] as 0 via false.
[-~!![]+-~!![]-~!![]]: ~ is a two's complement operator; ~1 is -2. Thus, this evaluates as -(-2)+-(-2)+-(-2), which is 6.
The remaining addends are analogous.
array + array will convert arrays to strings; thus [1]+[0]+[1]+[6]... will give the string "1016..."
The plus at start will convert it to a number.
While working in my JS code today, I found the following situation and can not explain myself what should be the correct output ?
'sachin' > 2 // False
'sachin' < 2 // False
'sachin' == 2 // False
I expect result of either of < or > should be true. What am I missing ?
When the runtime attempts to convert 'sachin' to a number, it will fail and end up as NaN. That special constant results in false for any comparison to any other numeric value. The NaN constant ("Not A Number") is not equal to any other value, nor is it less than or greater than any other value.
edit — the ==, <, and > operators all "prefer" numbers to strings. If one operand is a number and the other a string, they'll always try to interpret the string as a number. It doesn't matter what order the operands appear in; what matters is the operand types.
(Strictly speaking, the results of < and > when NaN is involved are supposed to be undefined, according to the spec, but Firefox seems to give false instead.)
if([] == false) alert('empty array is false');
alert(+[]) // alert 0
if([]) alert('empty array is true');
They both will run the alert
Demo
Both current answers here are correct, but I'd like to add a more detalied explanation based on the language specification. The reason for the apparently contradictory outcomes is that if statements and equality comparisons are evaluated differently.
In the case of an if(expression) statement, the expression is evaluated and then converted to the boolean type (§ 12.5). Arrays are Objects, and when an Object is converted to Boolean, the result is always true (§ 9.2).
Equality comparisons with == follow a different set of rules, detailed on § 11.9.3. The comparison may require multiple type conversions, until both operands are the same type. The order of the operands is also important. According to that algorithm, we can see that the comparison [] == false is actually a four-step operation:
There is a Boolean involved, so it's converted to a Number first (step 7 of the algorithm). So it becomes:
[] == 0
Then the array is converted to its primitive value (see § 9.1 and § 8.12.8), and becomes an empty string (step 9). So:
"" == 0
When comparing a String to a Number, the String is converted to Number first (step 5, following the rules described on § 9.3.1):
0 == 0
Now that we have two Numbers, the comparison evaluates to true according to step 1.c.iii.
It's because of type coercion of the == (equality) operator.
An empty array is considered truthy (just like an empty object), thus the second alert is called.
However, if you use ([] == false), your array is coerced to its string representation* which is "" which then is considered as a falsy value, which makes the condition true thus triggering the first alert too.
If you want to avoid type coercion, you have to use the === (identity) operator which is the preferred and by the famous Douglas Crockford promoted way to compare in javascript.
You can read more on that matter in this exhaustive answer.
*(Object.prototype.toString is called on it)
EDIT:
fun with JS-comparison:
NaN == false // false
NaN == true // also false
NaN == NaN // false
if(NaN) // false
if(!NaN) // true
0 == '0' // true
'' == 0 // true
'' == '0' // false !
This shows you the real "power" of Comparison with == due to the strange rules mentioned in bfavarettos answer.
There is a difference between evaluating a value as a boolean, and comparing it to true or false.
Whe using the == operator, the values are converted so that the types correspond. The [] value converted to the empty string "", and converting that in turn to a boolean gives false, so [] == false becomes true.
Evaluating [] as a boolean value will return true, because it is not a 'falsy' value, i.e. 0, false, null, "", NaN or undefined.