Javascript: Comparing standard functions always returns *false* - javascript

Im trying to understand why comparing standard functions always returns a Boolean false
Like for the isNaN function
>isNaN === true
false
>isNaN === false
false
But
>Boolean(isNaN)
true
Now to make things a little more interesting
>!isNaN === false
true
>!isNaN === true
false
This occurs with standard function like Number, Object etc.
Does anyone know what happens under the hood in JavaScript ?

I recommend you read truthy and falsy values, in short, isNaN is a function, it actually exists, so you can use it as a short hand for true checking, very useful for everyday programming.
When you use === type checking is done, and then a bool != a function.
When you pre-pend ! to it, you are actually casting to boolean type and reversing the value to true so that is why the comparison changes.

Here are the lists of Truthy and Falsy values.
isNaN is truthy because it's a function.

>isNaN === true
false
>isNaN === false
false
Because isNaN is a function.
>Boolean(isNaN)
true
Because again, isNaN is a function and functions are truthy values. Please refer following to see output specs for Boolean

Related

Why does NaN = !NaN return true?

NaN is one of those vestigial implementations of questionable origins, but for the most part I get it. However, I typed this into a Node prompt today and couldn't really make sense of it...
NaN = !NaN
> true
Is this simply returning the evaluated result of !NaN? This makes sense, but I'm surprised that there's not an error when attempting to assign NaN to another value.
Note: this question is about this specific syntax structure; there are a lot of questions related to NaN and isNaN out there but I couldn't find an answer after googling. Thanks to Ori Drori for the best answer thus far.
console.log(NaN = !NaN);
You are assigning true to NaN instead of comparing NaN to !NaN using === or ==, so the operation returns the assigned value -> true. Javascript ignores this assignment silently because NaN is read only.
console.log(NaN = true);
// NaN hasn't changed
console.log(NaN);
If you'll add use strict to your code, JS will throw a read only error instead:
'use strict';
NaN = true;
= is the asignment operator.
== and === are comparison operators.
NaN == !NaN
false
NaN === !NaN
false
Perhaps more surprisingly:
NaN == NaN
false
NaN === NaN
false
For more about NaN: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/NaN
Try running Javascript in a strict mode to avoid most of the problems.
NaN, null, false, "", null, undefined, 0 etc they are considered as falsy values (remember falsy !== false) in javascript, no matter you use a strict mode or not.
// 'use strict';
console.log(!NaN); // true
console.log(!null); // true
console.log(!false); // true
console.log(!""); // true
console.log(!null); // true
console.log(!undefined); // true
console.log(!0); // true
It is true in Python as well, except for NaN. For example,
print(not False) # True
print(not None) # True
print(not float("NaN")) # False
print(not "") # True
print(not 0) # True
Source of confusion
When we use multiple languages sometimes it can be a source of confusion.
For example,
In Python 'cat' in ['fat', 'cat', 'rat', 'hat'] returns True.
In Javascript 'cat' in ['fat', 'cat', 'rat', 'hat'] (exactly the same piece of code) returns false no matter you use a strict mode or not.
In Python print(not []) returns True.
In Javascript console.log(![]); returns false.
This is one of the reasons why I always love to use debuggers, REPL etc no matter how simple the code is.
Using = operator, you assign the value to a variable. However, what you don't know is by doing that, it returns the value of what is being assigned. Typing:
v = 1
in a JavaScript REPL will display 1, because that is what was assigned to v. So, doing:
NaN = !NaN
Will assign the opposite value of NaN to NaN itself. Since NaN in boolean is false, then !NaN in boolean must be true.
Javascript is really weird: When you write
NaN = true // true
which you basically do in your statement, you get "true". This is the same behavior as when you write
a = true // true
where the right side of the assignment is returned. But if you add var and write
var a = true // undefined
then nothing is returned. Also if you replace NaN with an expression that evaluates to NaN, for example
1/"a" = true // error!
then you get a ReferenceError. I recommend to never use the return values of assignments. The behavior is inconclusive and your code will be hard to read. You can enable "strict mode" to check this for you.

Need clarification understanding _.some()

It may be that I'm just very groggy this morning, but I'm having trouble understanding why this returns as true:
_.some([null, 0, 'yes', false]); // true
I know that _.some() returns true if at least one of the elements passes the predicate test as true. But from my understanding, if no predicate is provided, _.identity() is used. But console.log-ing each of those elements individually with _.identity() didn't return true for any of them. So why does it return true?
Without a predicate, some uses identity, which uses the value itself, and 'yes' is truthy.
A quick dive through the annotated source (paying special attention to cb and the handling of missing predicates there) leaves you with, essentially, a coercion to boolean when they do:
if (predicate(obj[currentKey], currentKey, obj)) return true;
No predicate means you're working with the original value there, so if ('yes'), which is true.
You're not seeing true in the console for any of those values because _.identity will return the value itself (so 'yes') rather than coercing it to a boolean. If you were to do !!'yes' (coercion and double-not), you will see true.
'yes' is truthy:
_.some([null]) // false
_.some([0]) // false
_.some(['yes']) // true
_.some([false]) // false
From the Truth, equality in javascript link:
The construct if ( Expression ) Statement will coerce the result of evaluating the Expression to a boolean using the abstract method ToBoolean for which the ES5 spec defines the following algorithm:
string: The result is false if the argument is the empty String (its length is zero); otherwise the result is true.
It doesn't need to return the literal value true, it only needs to return a truthy value (although you always should return only booleans).
The non-empty string 'yes' is truthy (you can test by Boolean('yes') or !!'yes').

Why does the following evaluate to 'hi'?

Why does the following evaluate to 'hi'?
'hi' || true || 50
I'm not super new to javascript, but I'm rebeefing my knowledge by going through some old books and I for the life of me do not understand why this evaluates to 'hi' instead of true.. Can someone explain this??
Welcome to the world of truthy and falsey values.
If a value can be converted to true, the value is so-called truthy. If
a value can be converted to false, the value is so-called falsy.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
This means that basically everything except
false
null
undefined
NaN
""
0
Will evaluate to true in || conditions, returning the first value that is truthy. This is sometimes used in a coalesce-like way:
a = a || {}
Which will set a to a if a is none of the values above, else an empty javascript object.
Because 'hi' is a non-empty string literal which evaluates to true when treated as a boolean. The expression a || b || c returns the first expression which evaluates to true, in this case 'hi'.
From MDN (Logical Operators):
Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand can be converted to true; if both can be converted to false, returns false.
Hey thanks everybody for your input. Yeah, now it makes sense because I remember how the first value that evaluates to true is the one that it will evaluate to. I guess I have to do some more studying on the truthy stuff because yeah, it is simple, but in a way it is somewhat confusing at times. Thanks again!!

Why does "undefined equals false" return false?

When I compare undefined and null against Boolean false, the statement returns false:
undefined == false;
null == false;
It return false. Why?
With the original answer pointing to the spec being deleted, I'd like to provide a link and short excerpt from the spec here.
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
The ECMA spec doc lists the reason that undefined == false returns false. Although it does not directly say why this is so, the most important part in answering this question lies in this sentence:
The comparison x == y, where x and y are values, produces true or false.
If we look up the definition for null, we find something like this:
NULL or nil means "no value" or "not applicable".
In Javascript, undefined is treated the same way. It is without any value. However, false does have a value. It is telling us that something is not so. Whereas undefined and null are not supposed to be giving any value to us. Likewise, there is nothing it can convert to for its abstract equality comparison therefore the result would always be false. It is also why null == undefined returns true (They are both without any value). It should be noted though that null === undefined returns false because of their different types. (Use typeof(null) and typeof(undefined) in a console to check it out)
What I'm curious of though, is that comparing NaN with anything at all will always return false. Even when comparing it to itself. [NaN == NaN returns false]
Also, another odd piece of information: [typeof NaN returns "number"]
Strict Equality
If possible, you should avoid using the == operator to compare two values. Instead use === to truly see if two values are equal to each other. == gives the illusion that two values really are exactly equal when they may not be by using coercion. Examples:
5 == "5" is true
5 === "5" is false
"" == false is true
"" === false is false
0 == false is true
0 === false is false
From the incomparable MDN, sponsored by the company of JavaScript's creator.
JavaScript provides three different value-comparison operations:
strict equality (or "triple equals" or "identity") using ===,
loose equality ("double equals") using ==,
and Object.is (new in ECMAScript > 6).
The choice of which operation to use depends on what sort of
comparison you are looking to perform.
Briefly, double equals will perform a type conversion when comparing
two things; triple equals
will do the same comparison without type conversion (by simply always
returning false if the types differ); and Object.is will behave the
same way as triple equals, but with special handling for NaN and -0
and +0 so that the last two are not said to be the same, while
Object.is(NaN, NaN) will be true. (Comparing NaN with NaN
ordinarily—i.e., using either double equals or triple equals—evaluates
to false, because IEEE 754 says so.) Do note that the distinction
between these all have to do with their handling of primitives; none
of them compares whether the parameters are conceptually similar in
structure. For any non-primitive objects x and y which have the same
structure but are distinct objects themselves, all of the above forms
will evaluate to false.
For a visual overview of the whole picture of equality in JavaScript:
https://dorey.github.io/JavaScript-Equality-Table/
The truth is, this seemingly "bad" aspect of JavaScript is a source of power when you understand how it works.
So undefined really means undefined. Not False, not True, not 0, not empty string. So when you compare undefined to anything, the result is always false, it is not equal to that.
You question is half, as we compare undefined/ null to any other types.
we will have false return.
There is no coercion happening, even we are using == operator.
This is so because it is so. :)
Read the ECMA standards here: https://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
Undefined is not the same thing as false, false is a boolean object (which has a value of 0 therefore it is indeed defined).
An example:
var my_var;
var defined = (my_var === undefined)
alert(defined); //prints true. It is true that my_var is undefined
my_var = 22;
defined = (my_var === undefined)
alert(defined); //prints false. my_var is now defined
defined = (false === undefined)
alert(defined); //prints false, false is defined
defined = (true === undefined)
alert(defined); //prints false, true is defined
According to the specification flow:
If Type(y) is Boolean, return the result of the comparison x ==
ToNumber(y).
1) undefined == false; -> undefined == Number(false); -> undefined == 0;
2) null == false; -> null == Number(false); -> null == 0;
There is no rule for these cases, so go with the behavior in the last step:
Return false.

Can someone explain this 'double negative' trick? [duplicate]

This question already has answers here:
What is the !! (not not) operator in JavaScript?
(42 answers)
Closed 8 years ago.
I am by no means an expert at Javascript, but I have been reading Mark Pilgrim's "Dive into HTML5" webpage and he mentioned something that I would like a better understanding of.
He states:
Finally, you use the double-negative trick to force the result to a Boolean value (true or false).
function supports_canvas() {
return !!document.createElement('canvas').getContext;
}
If anyone can explain this a little better I would appreciate it!
A logical NOT operator ! converts a value to a boolean that is the opposite of its logical value.
The second ! converts the previous boolean result back to the boolean representation of its original logical value.
From these docs for the Logical NOT operator:
Returns false if its single operand can be converted to true; otherwise, returns true.
So if getContext gives you a "falsey" value, the !! will make it return the boolean value false. Otherwise it will return true.
The "falsey" values are:
false
NaN
undefined
null
"" (empty string)
0
Javascript has a confusing set of rules for what is considered "true" and "false" when placed in a context where a Boolean is expected. But the logical-NOT operator, !, always produces a proper Boolean value (one of the constants true and false). By chaining two of them, the idiom !!expression produces a proper Boolean with the same truthiness as the original expression.
Why would you bother? Because it makes functions like the one you show more predictable. If it didn't have the double negative in there, it might return undefined, a Function object, or something not entirely unlike a Function object. If the caller of this function does something weird with the return value, the overall code might misbehave ("weird" here means "anything but an operation that enforces Boolean context"). The double-negative idiom prevents this.
In javascript, using the "bang" operator (!) will return true if the given value is true, 1, not null, etc. It will return false if the value is undefined, null, 0, or an empty string.
So the bang operator will always return a boolean value, but it will represent the opposite value of what you began with. If you take the result of that operation and "bang" it again, you can reverse it again, but still end up with a boolean (and not undefined, null, etc).
Using the bang twice will take a value that could have been undefined, null, etc, and make it just plain false. It will take a value that could have been 1, "true", etc. and make it just plain true.
The code could have been written:
var context = document.createElement('canvas').getContext;
var contextDoesNotExist = !context;
var contextExists = !contextDoesNotExist;
return contextExists;
Using !!variable gives you a guarantee of typecast to boolean.
To give you a simple example:
"" == false (is true)
"" === false (is false)
!!"" == false (is true)
!!"" === false (is true)
But it doesn't make sense to use if you are doing something like:
var a = ""; // or a = null; or a = undefined ...
if(!!a){
...
The if will cast it to boolean so there is no need to make the implicit double negative cast.
! casts "something"/"anything" to a boolean.
!! gives the original boolean value back (and guarantees the expression is a boolean now, regardless to what is was before)
The first ! coerces the variable to a boolean type and inverts it. The second ! inverts it again (giving you the original (correct) boolean value for whatever you are checking).
For clarity you would be better off using
return Boolean(....);
document.createElement('canvas').getContext may evaluate to either undefined or an object reference. !undefined yields true, ![some_object] yields false. This is almost what we need, just inverted. So !! serves to convert undefined to false and an object reference to true.
It's to do with JavaScript's weak typing. document.createElement('canvas').getContext is a function object. By prepending a single ! it evaluates it as a boolean expression and flips the answer around. By prepending another !, it flips the answer back. The end result is that the function evaluates it as a boolean expression, but returns an actual boolean result rather than the function object itself. Prepending !! is a quick and dirty way to typecast an expression to a boolean type.
If document.createElement('canvas').getContext isn't undefined or null, it will return true. Otherwise it will return false.

Categories