what does the term [0] == ![0] means? Though they return true.But i need to explain how it returns true as type of [0] is object and ![0] returns boolean? So how they are equal? Thanks
![0] is simply false, since all non-null objects cast to true.
When comparing [0] and false, they are converted to numbers - don't ask why, that's just the way it is. [0] is first converted to the string "0" (arrays cast to strings by concatenating the entries with , for a separator), which is then the number 0. false is cast to the number 0, and there you have it: [0] == ![0] is equivalent to 0 == 0, which is true.
To understand this, go through ![0] expression first. It evaluates to false - as [0] (as any Object in JS) is a truthy value. So the statement becomes...
[0] == false
Now it's easier: false is converted to 0 (for Boolean -> Number rule), and [0] is converted by Object-To-Primitive rule - first to '0' (String), then to 0 (Number). Obviously, 0 is equal to 0. )
P.S. And yes, it may seem quite weird, but both...
[0] == false
... and ...
![0] == false
... evaluate to true: the former is already explained, the latter is just false == false. Anyone still surprised by those == Lint warnings? )
You have split the expression into multiple parts:
typeof([0]) // "object"
[0] == true // false
![0] == true // false
![0] == false // true
The reason for this because in JavaScript only the value 1 is implicitly converted to true, so all other values are converted to false. The ![0] only negates a false expression thus it becomes (false == false) == true.
Related
This question already has answers here:
What does "!" operator mean in javascript when it is used with a non-boolean variable?
(5 answers)
Closed 2 years ago.
I looked a lot, but I couldn't find an answer for this especific case.
Why does this expression return true?
let variable = 0
!variable // true
I understand that the ! mark checks if a value is null or undefined, but in this case variable is defined. This is tricking me.
Isn't 0 really considered a valid value?
! is known as the logical NOT operator. It reverses the boolean result of the operand (or condition)
0 is also considered as the boolean false, so when you use !variable you are using the logical operator and saying it to change the value of the variable to its opposite, that in boolean is true
0 == false == !1 == !true
1 == true == !0 == !false
in Javascript are considered false:
false, null, undefined, "", 0, NaN
are considered true:
true, 1, -0, "false". <- the last one is a not empty string, so its true
if( false || null || undefined || "" || 0 || NaN) //never enter
if( true && 1 && -1 && "false") //enter
https://developer.mozilla.org/en-US/docs/Glossary/Falsy
To quote MDN Web docs, the Logical NOT !:
Returns false if its single operand can be converted to true; otherwise, returns true
So in your case it returns true because 0 can be converted to false
You can check out this link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
console.log(false === 0) // false
console.log(false === !1) // true, why does it equate to true using !?
and vice versa for
console.log(true === 1 ) // false
console.log(true === !0) // true
I understand the difference between equality and identity but couldn't understand this behaviour of JS . Please explain ?
The === requires that both values are the same type, no implicit coercion is performed.
When you compare a boolean to a number with triple ===, you will always get false, since they are not the same type.
But using ! in front of a number (or anything else) will convert it to Boolean first, (!x is same as !Boolean(x)) so the strict comparison can succeed. (actually, using ! on anything will coerce it to a Boolean in JS)
Rules of conversion number-to-boolean conversion :
For the number-to-boolean conversion, 0 and NaN are coerced to false, and any non-zero number is coerced to true. (FYI, null, undefined and the empty string '' are the only other falsy values in JS)
Now, you will have two boolean to compare, and === will return true or false accordingly.
So, to summarize :
in !1, 1 is non-zero, so it gets coerced to true, and !true gives false
so false === !1 is equivalent to false === false, which is a true statement.
You can work out the details for the other comparison.
As an additional resource, if you have time and are interested in learning more, I recommend the very good free ebook "You don't know JS".
Because !1 is treated as a boolean value in JS whereas 0 or 1 are interpreted as number.
You can use JS typeof !1 and typeof 0 to see the difference.
Since, false is also a boolean type, matching it with 0 (number) will result false.
Hope that clears it up.
When you do false === 0, it's comparing the boolean false to the integer 0. In contrast, when you do false === !1, javascript converts the integer 1 to a boolean and the unary ! acts as a "not" operation on what is effectively true. Since 1 is truthy in javascript, !1 converts to false. And vice-versa.
console.log(0) // 0
console.log(!0) // true
console.log(1) // 1
console.log(!1) // false
!1 is a Boolean (because of the logical NOT operator (!)).
true and false are also Boolean values.
0 is a Number.
Values of different types are never identical (===).
JavaScript will first convert your inverted numer to a boolean:
console.log(false === 0)
-> false
console.log(false === !1)
-> false === false
-> true
and vice versa for
console.log(true === 1 )
-> false
console.log(true === !0)
-> true === true
-> true
Do you understand the difference between an integer and a boolean?
console.log(false === 0) // false
console.log(false === !1) // true
console.log(true === 1 ) // false
console.log(true === !0) // true
console.log(!1) // false
console.log(!0) // true
Identity comparison checks that an object is exactly that, and 1 is not true, neither is 0 false.
Because ! operator convert any value to Boolean type and you are checking against another Boolean that's why false === !1 is giving you true.
Why NaN === false => false, isn't NaN falsy?
Why NaN === NaN => false, but !!NaN === !!NaN => true
I've been racking my brain trying to figure this out.
Falsy and being strictly equal to false are very different things, that's why one has a y instead of an e. ;)
NaN is spec'd to never be equal to anything. The second part of your question is comparing false === false, which is funnily enough, true :)
If you really want to know if something is NaN, you can use Object.is(). Running Object.is(NaN, NaN) returns true.
1.Why NaN === false => false, isn't NaN falsy?
The term "falsy" isn't defined in ECMA-262, it's jargon for where type conversion coerces a value to false. e.g.
var x = NaN;
if (!x) {
console.log('x is "falsy"');
}
The strict equality operator uses the Strict Equality Comparison Algorithm which checks that the arguments are of the same Type, and NaN is Type number, while false is Type boolean, so they evaluated as not equal based on Type, there is no comparison of value.
2.Why NaN === NaN => false, but !!NaN === !!NaN => true
Because the strict equality comparison algorithm states that NaN !== NaN, hence the isNaN method.
Using ! coerces the argument to boolean using the abstract ToBoolean method, where !NaN
converts to true and !!NaN converts to false, so:
!!NaN === !!NaN --> false === false --> true
Note that the abstract equality operator == will coerce the arguments to be of the same Type according to the rules for the Abstract Equality Comparison Algorithm. In this case, NaN is Type number, so false is converted to a number using toNumber which returns 0. And 0 is not equal to NaN so:
NaN == false --> NaN == 0 --> false
This condition:
NaN === false
Is always false because numbers are not booleans. To test if a value is falsy you can use a ternary expression:
NaN ? "truthy" : "falsy" // falsy
Why NaN === NaN => false
This is explained in MDN; pragmatically speaking, though, two values of which you only know they're not numbers can't logically be the same thing.
... but why is !!NaN === !!NaN => true
This is because casting NaN into a boolean will make it false and booleans can be compared as per normal.
=== compares both type and value.
Even though NaN is falsey, === wouldn't be the way to compare it. Something is "falsey" if it evaluates to false in a boolean expression. That isn't the same as being equal to (or equivalent to) false.
For example, null == false returns false, even though null is falsey. This is not completely intuitive, but that's just how JavaScript handles false/falsey values.
0 and the blank string ("") are special cases where value equality comparisons against false evaluate to true (i.e. 0 == false and "" == false). However, 0===false and ""===false still returns false.
NaN is special in that it doesn't have a real value, so comparing it to itself doesn't return true. Essentially, NaN is equal to nothing, not even NaN.
The only way to reliably compare something to NaN is using isNaN( value ).
To your second point, !value is a boolean expression. value first undergoes type coercion to a boolean (and remember, NaN is falsey) and then the boolean NOT ! makes it true. As it happens, it's double negated, so !!NaN is the same as boolean false. Of course false === false, so the expression evaluates to true.
Why NaN === false => false, isn't NaN falsy?
NaN as you are using, is a global property initialized with value of Not-A-Number. It's not boolean. It's NaN data type as defined by IEEE 754.
It's the "same thing" you compare null === false (or even null == false).
In this case, there is no difference using sctric equal or not: NaN == false, also will return false!
Why NaN === NaN => false, but !!NaN === !!NaN => true
2.1. NaN ==== NaN, is false by definition.
2.2. But in !!NaN === !!NaN, you aren't comparing NaNs anymore, when you do ![value], you "evaluate" it (or cast to a boolean).
I'm gonna now explain with null, because it's more used, so you can apply it to NaN:
Casting NaN, it's the same thing that casting null.
null == false? true : false // false! because it's not a bool false.<br>
!null? true: false // true! because !null -> true -> if(true)...
More Refs:
http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.1.1
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN
This comparison also returns false:
const x = NaN
const y = x
console.log(x === y) // false
NaN and false are both the subset of Falsy.
NaN == false -> they're both falsy -> thus 'TRUE'
NaN === false -> they're NOT the same type -> thus 'FALSE'
Consider empty JavaScript array:
var a = [];
alert(a == false); // shows true
alert(!a); // shows false!
How to explain this?
What are the rules?
From http://forums.whirlpool.net.au/archive/966449:
a == false:
In this case, the type of the left-hand side is object, the type of the right-hand side is boolean. Javascript first converts the boolean to a number, yielding 0. Then it converts the object to a "primitive", yielding the empty string. Next it compares the empty string to 0. The empty string is converted to a number, yielding 0, which is numerically equal to the 0 on the right-hand side, so the result of the entire expression is true.
See ยง11.9.3 of the ECMAScript spec for all the gory details.
(!a):
In this case Javascript converts the object to the boolean true, then inverts it, resulting in false.
The ! operator checks whether its operand is "falsy".
The following are true:
!false
!0
!null
!NaN
!undefined
!""
The == operator checks for loose equality, which has nothing to do with falsiness.
Specifically, a == b will convert to operands to numbers, then compare the numbers.
Strings containing numbers convert to the numbers that they contain; booleans convert to 0 and 1.
Objects are converted by calling valueOf, if defined.
Thus, all of the following are true:
"1" == 1
"0" == false
"1" == true
"2" != true
"2" != false
({ valueOf:function() { return 2; } }) == 2
({ valueOf:function() { return 1; } }) == true
The == operator when one of the operands if Boolean, type-converts the other to Number.
[] == 0;
Is equivalent to:
0 == 0;
You can see the complete details of The Abstract Equality Comparison Algorithm on the specification.
As you can see, an empty array object, when converted to Number, produces 0:
+[]; // 0
Number(0);
This is really because its toString method produces an empty string, for example:
[].toString(); // ""
+""; // 0
Number(""); // 0
When comparing an object to a primitive value via the == operator, the object coerces into an primitive value itself (number or string). In this case [] coerces into 0, then false coerces into 0:
[] == false
0 == false
0 == 0
which is true.
The ! operator coerces into boolean and then inverts the value. [] into boolean is true (like with any object). Then invert to become false
![]
!true
false
Not sure if this answers the question, but there is a new library for getting around all of Javascript's Typecasting weirdnesses:
Typecast.js
In a sentence, Typecast solves all the simple problems, so you can focus on the big ones. Typecast fixes what's wrong with Javascript by creating a complete platform for strongly-typed variables in Javascript.
Code-snippet 1:
if ( !x ) { /* do stuff */ }
Code-snippet 2:
if ( x == 0 ) { /* do stuff */ }
For what values of x do these two code-snippets differ?
I am asking because, although I read the chapter on == in the spec, I still find it hard to deal with situations like the above (where it is combined with ToBoolean coercion).
btw, I want to know this just for the sake of knowing it (I want to understand the language), so don't bother telling me about === or asking me what x is.
Update: I corrected the fist snippet. I meant !x.
[] == 0 is true; ![] is false
null == 0 is false; !null is true
NaN == 0 is false; !NaN is true
undefined == 0 is false; !undefined is true
!x will check whether x is "falsy".
x == 0 will check whether x is "equivalent to" 0.
Both of these terms are defined by the Javascript spec.
The following will give you true for the first and false for the second snippet:
NaN
null
undefined
And these will give you false for the first and true for the second snippet:
[]
"0" and any other string that converts to 0 using Number(x) such as "00", "000", "+0", and "-0" (which I will now call "noughty strings")
an array containing a single element that is 0, null, undefined or an empty or noughty string.
For everything else you'll get the same result for both snippets, although there may be one or two more cases I haven't thought of.
Here's an interesting one with regard to a non-empty String that has only space characters:
!!" "; // true
" " == true; // false
This is because when you do a == comparison, and one of the values being compared is a number or a boolean, an attempt is made to convert the other value to a number.
The reason you get the different result is that a string with only space characters converts to the number 0 (or falsey), while a string with only spaces converted to boolean via !! is seen as a non-empty string, and therefore true.
So:
var x = " ";
alert( !x ); // false
alert( x == 0 ); // true
EDIT:
Probably the key thing to remember is that when comparing a number or boolean to a non number type, == uses toNumber conversion if possible, while ! uses toBoolean conversion. They're not always the same.
It is easy to see the result of the toBoolean conversion using !!. As in:
alert( !![] ); // true
But you can't really see the result of the toNumber conversion when using ==.
You can, however, use the unary + to see the result of a toNumber conversion. As in:
alert( +[] ); // 0
I'm pretty sure that what happens in the case of an Array, is that it first gets a toString call. Therefore:
// ---------------------toString result-------toNumber result (from string)
alert( +[] ); // "" 0
alert( +[""] ); // "" 0
alert( +[" "] ); // " " 0
alert( +[0] ); // "0" 0
alert( +["0"] ); // "0" 0
alert( +["3"] ); // "3" 3
alert( +[3,4] ); // "3,4" NaN
Short answer: the two are almost always the same but not 100% the same.
An example would be (!'0') which is false whereas ('0' == 0) is true
Details:
From: http://www.joeyjavas.com/2007/08/04/javascript-true-false-checking-for-boolean-values/
Checking if a value is true or false is simple in JavaScript. All values evaluate to true, except for:
0
-0
null
undefined
NaN
empty string
false
Therefore, (!x) will be true for all of the above values of x and only those.
As for (x == 0), it will be true for any value of x which - when converted according to "==" conversion rules - is converted to 0 when compared to a number (for example, Boolean false value). Other examples that compare true to ==0 are objects which generate 0 from their valueOf() methods, or a string '0', or an empty Array ([])
The first test will succeed when x is non-zero, or evaluates to an object (as opposed to null or undefined), or is a non-empty string. So if x is 0 then the condition fails, but if it is "0" then it succeeds.
The second test will succeed when x is convertible to 0. This means it must not be null, undefined, or an object to pass this test. And it may be "0" or "".
In other words, these conditionals are not opposites. The value "0" will pass both tests, for example.
Code Snippet 1 will execute if x is "falsy" value. In Javascript, this means 0, -0, null, undefined, NaN, "", or false. Code Snippet 2, however, will only execute if x is zero. Unlike the first condition, this does not include other "falsy" values.
The difference between the two is that
if ( x ) { ... }
Tests whether x is "truthy"
Whereas
if ( x == 0 ) { ... }
Does type coercion between x and 0.
I presume you mean something like
if (x == 0) vs if (!x)
The main difference is type coercion of x to a number vs checking if x is falsy.
Clearly NaN itself will never equal 0 since its not a number. undefined will also coerce to NaN so that is not caught by == 0 I can't give a good explanation why null is not caught by 0 since Number(null) == 0
After some lookups, have to change my awnser.
There's no simple logic, implicit equality operations follows an algorithm.
http://interglacial.com/javascript_spec/a-11.html#a-11.9.3
I can't sum it up better then what the algoritm describes, it would just get more confusing.
So it's (!x) is equivalent to (typeof x === false) aka (not true)
And (x == 0) gets compared by algorithm.