&& operator on strings in javascript - 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

Related

What operator checks type but not value?

So I recently learned about == and === which have been helpful, but I was wondering if there was one like this but only for types. Like it checks if they're both numbers but it doesn't matter what number they are.
You are probably looking for typeof
Ej:
var a = 1;
var b = '2';
var c = typeof b === typeof a; // c is false

You Don't Know JS: Up & Going - example problem

In page 38 I found - arrays are by default coerced to strings by simply
joining all the values with commas (,) in between. You might think
that two arrays with the same contents would be == equal, but
they’re not:
var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";
a == c; // true
b == c; // true
a == b; // false
But when I run my code like the following:
var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";
console.log(typeof a == c); // false
console.log(typeof b == c); // false
console.log(typeof a == b); // false
I got different answers! Why typeof a == c and typeof b == c is false here?
its doing
typeof a == c
=> (typeof a) == c
=> "object" == c // which is false
basically typeof operator works before == sign
My cliche advice, always use paranthesis to make your intent clear
typeof (a==b) vs (typeof a) == b
The typeof operator returns the type of the content of a variable as a string. So if your variable a contains an array, typeof a will return the string "object" (as arrays are a special kind of objects).
So typeof a == c and typeof b == c compare the string "object" with the string "1,2,3". As they are obviously not the same, this returns false.
Note that the typeof operator has a higher precedence than the == operator.

Why || operator is behaving like this?

Why _value is foo on second function call? It took me a while to find this bug.
function doSomething(value) {
console.log('should be:', value);
const _value = value || Math.random() > 0.5 ? 'foo' : 'bar';
console.log('actually is:', _value);
}
let values = ['foo', 'bar'];
const first = doSomething(values[0]);
const second = doSomething(values[1]);
To understand better I put a parenthes around the testing code:
(value || Math.random() > 0.5)
Since value is always defined (non null) the condition avaluates to true and assigns 'foo' to '_value'
Hope this explains it for you.
Because the expression
const _value = value || Math.random() > 0.5 ? 'foo' : 'bar';
is evaluated as:
const _value = (value || (Math.random() > 0.5)) ? 'foo' : 'bar';
The conditional operator has lower precedence than other operators in the expression.
value is a non-empty string, so it evaluates to true in boolean context. Thus, the condition evaluates to true, and the final result is always 'foo'.
Because:
> 'bar' == true
false
So:
const _value = value || Math.random() > 0.5 ? 'foo' : 'bar';
_value will be randomly assigned the value 'foo' or 'bar', because value is 'bar' which evaluates to false, so the second half of the or-expression || is evaluated and assigned to _value.
Try this.
const _value = value || (Math.random() > 0.5 ? 'foo' : 'bar');
Because JS in your code check such
`if(value || Math.random() > 0.5){
_value = 'foo';
}else{
_value ='bar'
}`
The construct const a = b || c is common Javascript shorthand. It means:
If b is not falsy assign it to a. Otherwise assign c to a.
It can also be written const a = b ? b : c; or
const a;
if (b) a = b;
else a = c;
A value is falsy generally speaking if it is empty or has the value zero.

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
}

'null's number value acting differently

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.

Categories

Resources