JavaScript operator precedence - javascript

According to Mozilla, the === operator has higher precedence than the || operator, which is what I would expect.
However, this statement evaluates to the number 1, rather than false.
let x = 1 || 0 === 0; // x === 1;
You have to wrap in parentheses to get a boolean:
let x = (1 || 0) === 0; // x === false;
What is the explanation?
Note: This is not a duplicate of this question, which does not have anything about equality operators - JavaScript OR (||) variable assignment explanation

Higher operator precedence is like a parenthesis around the operands.
let x = 1 || (0 === 0);
The second part gets never evaluated, because of the truthy value of 1
.

|| is a short circuit operator and conditions are evaluated from left to right.
So in left || right, if the left condition is true, the whole condition is evaluated to true and the right one is never evaluated.
In
let x = 1 || 0 === 0; // x === 1;
x = 1 assigns 1 to x and the second condition after || is never evaluated as if (1) is evaluated to true.
And in
let x = (1 || 0) === 0; // x === false;
(1 || 0) is evaluated to true as if (1) is still evaluated to true.
And then true === 0 is evaluated to false.
So x is valued to false.

Related

Operator precedence for logical AND (&& )and logical OR (||)

As per the operator precedence table for JavaScript, I can see that && has higher precedence than ||.
So, for the following code snippet:
let x, y;
let z = 5 || (x = false) && (y = true);
console.log(z); // 5
console.log(x); // undefined
console.log(y); // undefined
I thought that && should be evaluated first and after short-circuiting for the && part, x would be assigned the value false. And then only, || would be tried to be evaluated.
But, from the output of the console.log, I can clearly see that's not the case here.
Can someone please help me what am I missing here?
Thanks in advance.
What the operator precedence of && of || means is that this:
let z = 5 || (x = false) && (y = true);
gets evaluated as:
let z = 5 || ((x = false) && (y = true));
and not as
let z = (5 || (x = false)) && (y = true);
It's not something that indicates when the values on each side of an operator is evaluated. That's done by the mechanics of each individual operator. For example, for ||, it's specified here:
1. Let lref be the result of evaluating LogicalANDExpression.
2. Let lval be ? GetValue(lref).
3. Let lbool be ToBoolean(lval).
4. If lbool is false, return lval.
5. Let rref be the result of evaluating BitwiseORExpression.
6. Return ? GetValue(rref).
It evaluates GetValue(lref) before GetValue(rref) runs.
In other words, operator precedence indicates which tokens are applied to which operator, and in what order, but not how/when a given operator evaluates the values on its left and right side.

Evaluate multiple conditional statements with possible undefined variables

In Javascript, what would be the best way to evaluate several conditions when taking into consideration variables that could be undefined? For instance, I want to evaluate if x > y only if x is NOT undefined (has a value), and if it is undefined, continue to proceed to the next condition.
Something like:
if(x && x > y && a && a > b && c < d && e > f) ....
Here I want to see if x is defined, and then evaluate if x is greater than y, then go to evaluate if a is defined and evaluate if a is greater than b, then evaluate if c is less than d and etc. So here I want it so that if x or a is undefined CONTINUE to proceed to evaluate c < d and e > f
if(
x // if exists
&& x > y // (if x is defined then evaluate x > y, if not then go to:
&& a // if exists
&& a > b // (if a is defined then evaluate a > b, if not then go to:
&& c < d
&& e > f
) {
....
}
Here if the variables are are undefined then the whole statement is all false... what are some solutions for this that are clean?
You can do x > y directly, You need not do x && x>y, because they will produce same result and x>y syntactically correct as well
if(x>y) //when x=undefined and y=10, x>y will be false because undefined>10 is false
//when x=undefined and y=undefined x>y will be false because undefined>undefined is false
//when x=10 and y=undefined x>y will be false because 10>undefined is false
if(x > y && a > b && c < d && e > f)

Why is `x === x++` true and `x++ === x` false in Javascript?

Can you explain the difference between these two logical operations :
let x = 1;
console.log('x = ' + x);
console.log('x === x++ : ' + (x === x++));
x = 1;
console.log('x = ' + x);
console.log('x++ === x : ' + (x++ === x));
The postfix increment (y = x++), does increase the value, but evaluates to it's previous value. It barely equals:
x² = x; // evaluate previous value of x
x += 1; // increase x
y = x²; // use previous value
So therefore x === x++ is equal to:
// evaluate left side of ===
x¹ = x;
// evaluate right side
x² = x;
// ++
x += 1;
// comparison
x¹ === x² // true
wereas x++ === x is:
// evaluate left side
x¹ = x;
// ++
x += 1;
// evaluate right side
x² = x; // x was already incremented!
// comparison
x¹ === x²
x === x++ : first compare x with x then x++
x++ === x : first x++ and then compare the result of x++ with x
When evaluting the === operator in javascript, it evalate the left operand first, and then the right operand, and does the comparison in the last. See ecma262.
And, when x++ is evaluted, the value of x is changed, and the result of x++ is the original (unchanged) value of x.
So, in x === x++ ,both x and x++ evalutes to the original value of x,the value of x is changed after that. So the result is true.
In x++ === x, the value of x is changed when evaluating the left x++, and the left operand evaluates to the original value. But the right operand eveluates after this, so it evaluates to the changed value of x. So the result is false.
x++ is a post increment operator, it basically put the value of x already and then increment it by 1.
In the first case x===x++. It suggests, 1===1 while in the second case x++===x ,the value of x is incremented before the comparison, So it becomes 1===2,which is false of course.
This happens because the order of increment operator (before or after the variable) matters.
Using x++ will return the variable first then increment it, while using ++x will increment it first then return the result.
Example:
x = 0;
console.log(x++, x); // 0, 1 (first return the variable then increment)
console.log(++x, x); // 2, 2 (first increment then return the variable)
In the first comparison, you are incrementing it after all uses of variable:
x = 0;
// 0 === 0
x === x++
In the second comparison, you first use the x value, then increment it and compare with new x value:
x = 0;
// 0 === 1
x++ === x
Interesting.
In the second case, x++ is being evaluated as 1 then it increments x (becomes 2). So the comparison ends up being 1 === 2
This is basic computer science, x++ means use then update.
x = 1;
x === x++
here value of x is changed after comparison is over.
x++ === x
here in beginning, x++ value remains 1 but once === is executed, value of x changes to 2.
It's because the value x is incremented just before you read it again so x++ === x is false and x === x++ is true.
There is some other operator that looks almost the same ++x which increments variable immediately.
let x = 0;
console.log(x++); //0
console.log(x); //1
let y = 0;
console.log(++y); //1
console.log(y); //1
The operators ++ can be placed either after a variable.
When the operator goes after the variable, it is in “postfix form”: x++.
The “prefix form” is when the operator goes before the variable: ++x.
let x = 1;
console.log('x = ' + x);
//print x = 1
console.log('x === x++ : ' + (x === x++));
//(x === x++) that means
//(1 === 1)
//true
x = 1;
console.log('x = ' + x);
//print x = 1
console.log('x++ === x : ' + (x++ === x));
//(x++ === x) that means
//(1 === 2) works the same as x = x + 1, but is shorter
// false
First, I assume that the expression is evaluated from left to right, see the demonstration below:
console.log('(1 == 2) == 2 - left first - ', (1 == 2) == 2 )
console.log('1 == (2 == 2) - right first - ', 1 == (2 == 2) )
console.log('1 == 2 == 2 - same as left first - ', 1 == 2 == 2 )
or in ECMA 262
Theory done, so in x === x++, under the hood it transplies to
// init temporary variables x_left/x_right in CPU for the calculation
x_left = x_right = x;
// `===` is evaluated first:
x_left === x_right; // true
// then `x++` evaluate, doesn't affect the result `true` above
x_right += 1;
x = x_right;
And in x++ === x, it transpiles to
// init temporary variables for the calculation (in CPU)
x_left = x_right = x;
// `x++`
x_left += 1;
x = x_left;
// `===` operator
x_left === x_right; // false
x === x++ Here, x=1 before comparing, so returns true.
x++ === x Here, because of operator precedence,
this equals x === ++x where x is incremented and hence returns false.

If then logic with && ||

Can someone explain to me or point me to documentation as to why the following function doesn't work?
var x = 1;
var y = 2;
var z = 1;
function logicTest() {
if ((x && y && z) === 1) {
return true;
} else {
return false;
}
}
console.log(logicTest())
I know that I can type it out the long way as follows:
var x = 1;
var y = 2;
var z = 1;
function logicTest() {
if (x === 1 && y === 1 && z === 1) {
return true;
} else {
return false;
}
}
console.log(logicTest())
But I'm really trying to understand why the first doesn't work and also if there is a better way of typing the second if/then statement or if that is just the way it will always have to be.
Thanks!
The expression
((x && y && z) === 1)
first involves the evaluation of (x && y && z). To evaluate that, JavaScript tests, in sequence, the values of x, y, and z. If, left to right, one of those values when coerced to boolean is false, evaluation stops with that (uncoerced) value as the value of the whole thing. Otherwise, the value of that subexpression will be the value of z, because it's the last subexpression in the && sequence.
In this case, x, y, and z are all non-zero numbers, so the overall result will be 1, because z is 1.
What you seem to want to be able to do is test whether all of a set of subexpressions are equal to the same value. That, as you've found, can only be determined by explicit comparison. It's also something that could be done by creating a list and then using array functions to perform the tests, which would be useful when there are more than just three subexpressions to test.
Also, on a stylistic note:
function logicTest() {
if (x === 1 && y === 1 && z === 1) {
return true;
} else {
return false;
}
}
Performing tests with relational operators like === generates boolean values. It's more concise to take advantage of that:
function logicTest() {
return x === 1 && y === 1 && z === 1;
}

Logical operator || returns number instead of boolean value

I attached an example with two if conditions. The first if condition works as expected. The second if condition returns 11, but why? I know that the second if condition is wrong, but I would like to understand why Javascript returns in that case 11.
function exception(number) {
// if(number === 10 || number === 11) { // Working as expected
if(number === 10 || 11) { // Why 11?
console.log(number);
}
}
function loop(f) {
for (i = 0; i <= 100; i++) {
f(i);
}
}
loop(exception);
from this question.
(expr1 || expr2)
"Returns expr1 if it can be converted to true; otherwise, returns
expr2."
source
So when expr1 is (or evaluates to) one of these 0,"",false,null,undefined,NaN, then expr2 is returned, otherwise expr1 is returned
Some Information about what you where trying to achieve:
number === 10 || number === 11 is the same as (number === 10) || (number === 11)
number === 10 || 11 is the same as (number === 10) || (11) it does not compare 11 to number here
Now let's have a closer look atnumber === 10 || 11 :
number === 10 will be true if number is of type number and equal to 10
if the first was false, it will evaluate the boolean value of the next statement: 11 (wich is accepted as true, for beeing a number not equal to 0)
because Boolean(11) is true (try on your console)
so even if first condition is not true (if the number is not 10), then second condition will be true always

Categories