'null's number value acting differently - javascript

Into Ecma-262, it says number value of null is +0. So when I doing these:
var a = null; //so now a = 0
var b = 0;
var c = 1;
alert(a * c); //shows '0' as expected
alert(a < c); //shows 'true' as expected
alert(a > c); //shows 'false' as expected
alert(a === b); //shows 'false'
alert(a == b); //shows 'false' - why ?
I know from the Ecma-262 javascript treats +0 and -0 same. Then why it is showing false ?

While null is equivalent to +0 when used in arithmetic expressions, it doesn't actuall have the value +0. null is null, and if you compare it to something that is not null then it will be false.

Related

Why does comparing value with undefined returns false in JavaScript?

I am new to Javascript and I noticed when a variable is undefined, comparing a number returns false as below. Why does comparing undefined with numbers return false?
var a = undefined;
console.log(a < 10);
console.log(10 < a);
console.log(a == 10);
This is how works in JavaScript.
Number(undefined) // NaN
NaN == NaN // false
NaN < 0 // false
NaN > 0 // false
So, while you compare it forces to check like:
Number(undefined) < 10
// undefined is coerced to check with number
And thus,
undefined == 10 // false
undefined > 10 // false
undefined < 10 // false

What does this condition do in ternary?

Javascript Ternary Condition
I have javascript with this condition, what is this?
var y = (typeof x !== undefined) ? x || 0 : 1;
This (typeof x !== undefined) ? x || 0 : 1; is going to return always true because the typeof operator will return a string.
That condition should compare a string as follow:
(typeof x !== 'undefined') ? x || 0 : 1;
var x;
var str = typeof x !== 'undefined' ? x || 0 : 1;
console.log(str);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Conditional (ternary) Operator explanation:
+--- When condition is true
|
| +--- When condition is false
| |
| |
v v
typeof x !== 'undefined' ? x || 0 : 1;
^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| +---- The condition should be:
| (x === undefined ? 1 : x || 0)
|
+--- Checks for the type of x
Code refactored
var x = 4;
var str = x === undefined ? 1 : x || 0;
console.log(str);// should return 4
var y;
str = y === undefined ? 1 : y || 0;
console.log(str);// should return 1
y = null;
str = y === undefined ? 1 : y || 0;
console.log(str);// should return 0
y = 5;
str = y === undefined ? 1 : y || 0;
console.log(str);// should return 5
y = 5-"5";
str = y === undefined ? 1 : y || 0;
console.log(str); // should return 0
.as-console-wrapper { max-height: 100% !important; top: 0; }
Docs
Conditional (ternary) Operator
typeof
First, there is an error with the condition:
(typeof x !== undefined)
because you are comparing a type against a value.
typeof always returns a string, while undefined is a value. So, whatever type x is, it will be returned as as string. Even if it's value is undefined, "undefined" (notice the quotes?) will be returned as its type and since the string "undefined" has a typeof === "string", the condition will actually branch into the true section, even when x actually is undefined.
So, it needs to be: (typeof x !== "undefined").
Or, you could test the value of x against the value undefined:
(x !== undefined)
But, you can't mix and match values and types.
Now, assuming we correct that, the next part (the true branch):
x || 0
Simply returns x, as long as it is not "falsy" (that is, any value that would convert to the Boolean false). 0, false, NaN, undefined, "" or null are all falsy. So, if x is not falsy, x is returned. If x is falsy, then 0 is returned. This is a way to provide a default return value in case the first value doesn't exist. But, the logic is a bit off here, because if the code has entered the true branch, it's because x is not undefined, which means it's "truthy". And, if it's truthy, then we can safely just return x. So, it really should just be:
x
Finally, the last part (the false branch)
1
Is what will be returned if the original condition is false. In this case, if x is undefined.
So, the code has flaws in it and really should be:
(typeof x !== "undefined") ? x : 1
EXTRA CREDIT:
In reality, any expression you place into the condition of an if statement is going to be converted to a Boolean for the if to do its job. If all you need to know is if x is not a "falsy" value, then all you need to do is write:
x ? x : 1;
The x will be converted to a Boolean.
If it's true (truthy), then x is returned.
If it's false (falsy), then 1 is returned.
Examples:
function testX(x){
return x ? x : 1;
}
// Truthy:
console.log(testX(10)); // 10
console.log(testX({})); // {}
console.log(testX(true)); // true
console.log(testX("something")); // "something"
// Falsy:
console.log(testX("")); // 1
console.log(testX()); // 1
console.log(testX(4-"Z")); // 1 because 4-"Z" == NaN
console.log(testX(false)); // 1
console.log(testX(0)); // 1
console.log(testX(null)); // 1
The condition
(typeof x !== undefined)
asks if x is not of type undefined. Or, if x is defined. This will include any value or even null.
...? x || 0
If so, the expression evaluates to this. Which is the value of x in most cases or 0 if x is anything evaluated to be boolean false, e.g., null, false, etc.
... : 1;
Otherwise (i.e. case when x is undefined), evaluates to 1.
Typing in Javascript is complicated (in my opinion), sometimes it is not easy to remember what it is when you're comparing mixed type stuff, see https://dorey.github.io/JavaScript-Equality-Table/ for a summary matrix.
Admitting that you have a left-hand operand, it does the same thing as :
var y;
if(typeof x !== undefined) {
if(x)
y = x;
else
y = 0;
}
else
y = 1;

That Operator || in console.log() works like || operator?

How it's work for example;
let x;
console.log(x || 2); // 2
if
let x = 4;
console.log(x || 2); // 4
if
let x = 5;
let y = 7;
console.log( y || x || 2);
it's mean that console.log() write first value that is true ?
What you're seeing isn't related to console.log. It's called short circuiting.
When comparing values with ||, it will always return the first truthy value. If no truthy values are present, it will return the last value being compared.
let a = false || true;
let b = false || null || 'b';
let c = undefined || !a || 10;
let d = undefined || false || null; // no truthy values
console.log(a); // true
console.log(b); // 'b'
console.log(c); // 10
console.log(d); // null
let x = 5;
let y = 7;
console.log( y || x || 2); //return 7
expr1 || expr2 Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true.
Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators

NaN counts as false?

I'm reading a book "Eloquent JavaScript" by Marijn Haverbeke and it says:
"The rules for converting strings and numbers to Boolean values state that 0, NaN, and the empty string ( "" ) count as false, while all the other values count as true."
Would be very nice if someone explains me what did the author mean by saying that NaN counts as false according to the rules of converting?
As I can see it now:
0 == false; // true
"" == false; // true
NaN == false; // false
0 / 0 == false; // false
Yes I know that "NaN is not equal to anything, even to the other NaN", but I just wonder what does the book want me to know?
Basically, if a variable is assigned to NaN, it will evaluate to false if used in a conditional statement. For example:
var b = NaN;
if(b){//code will never enter this block
console.log('the impossible has occurred!')
}
This is true as well if you get invalid input, for example:
var input = "abcd"
var num = parseFloat(input);
if(num){
console.log('the impossible has occurred!')
}
var a = NaN;
var b = null;
var c;
var d = false;
var e = 0;
document.write(a + " " + b + " " + c + " " + d + " "+ e + "<br>");
if(a || b || c || d || e){
document.write("Code won't enter here");
}
if(a || b || c || d || e || true){
document.write("Code finally enters");
}
Reference: link
Other answers are correct, but the significant thing here is that a conversion to a bool takes place in the case that it's used in a condition.
That's why:
NaN === false // false
Yet:
if(NaN) // false because it first does a boolean conversion
// which is the rule you see described
As a side note, NaN == false as used in the question (note == vs ===) actually does a type conversion from false to 0 per the == operator. It's beyond the scope of this question, but the difference in operators is well documented elsewhere.
The book wants you to know that JavaScript evaluates NaN to false.
var notANumber = 500 / 0;
if(notANumber) {
// this code block does not run
}
else {
// this code block runs
}

&& operator on strings in javascript

I have the following expression :
if(a && b === c) {//do something}
What would be the meaning of this condition if I consider that a,b, and c are strings ?
This is equal to if (a == true && b === c). (note that == is lose comparison. Eg. "foo" is loosely equal to true, however "" is not loosely equal to true, hence this says "if a is not an empty string, and b has the same content, and is the same type as c, then do something")).
Examples:
var a = 'foo';
var b = 'bar';
var c = 'bar';
Will be true because a is not falsy (a non empty string is truthy), and b is the same type and has the same content as c.
var a = '';
var b = 'bar';
var c = 'bar';
Will be false because a is falsy (an empty string is falsy).
var a = 'foo';
var b = 'rab';
var c = 'bar';
Will be false because b does not have the same content as c.
var a = 'foo';
var b = true;
var c = 1;
Will be false because b is not the same type as c (boolean vs number - with == this would be true, as true == 1).
Your expression expands to this:
if (a) {
if (b === c) {
// do something
}
}
It first checks that a is some truthy value. It then checks that b and c are of the same value and the same type. Read up on truthy and falsey values in JavaScript.
This means:
a is truthy
AND
b exactly equal to c (including type)
Here a is truthy means it is NOT ('undefined' or "" or 'null' or 0 or 'NaN' or 'FALSE')
if a have some value (not null and "") and b's value (string, case sensitive) is equal to c's value then your code

Categories

Resources