Why does `(state == 1 && 3)` make sense? [duplicate] - javascript

This question already has answers here:
Why the result of bool(true) && string is string in javascript?
(4 answers)
Closed 8 years ago.
I came across this code in Mithril.js:
finish(state == 1 && 3)
To my (Java/C programmer's) eyes it looks like it should always invoke finish(true) if state is 1 and finish(false) if state is not 1. But it actually seems to do finish(3) for the former and finish(false) for the latter.
What is the logic behind this?
Is this idiomatic in JavaScript, or is it a bad idea? To me it's horribly obscure.

You can interpret the operators || and && like this:
A || B
→ A ? A : B
A && B
→ A ? B : A
But without evaluating A twice.

It is a characteristic of JavaScript, && and || operators always return the last value it evaluated.

In JavaScript, the && operator doesn't force the result to a boolean. It's instead similar to:
var _temp = state == 1;
finish(_temp ? 3 : _temp);
Testing the truthiness of the left side, then returning either the right when truthy or the left otherwise.

The comparison a && b actually returns the value the last value evaluated in the expression and not true or false.
You can refer to the spec:
The production LogicalANDExpression : LogicalANDExpression &&
BitwiseORExpression is evaluated as follows:
Let lref be the result of evaluating LogicalANDExpression.
Let lval be GetValue(lref).
If ToBoolean(lval) is false, return lval.
Let rref be the result of evaluating BitwiseORExpression.
Return GetValue(rref).

Related

Understanding JavaScript evaluation [duplicate]

This question already has answers here:
Operator precedence with JavaScript's ternary operator
(7 answers)
Closed 3 years ago.
I am fixing some code and trying to understand a certain evaluation that is happening. There was a little snippet written where 2 evaluations should happen like so :
const active = true;
const isPerson = true;
const person1Time = null;
const person2Time = null;
// this one is not working as intended
const original = !active && isPerson ? !person1Time : !person2Time;
console.log("original", original);
// fixed when second evaluation is wrapped in parens
const fix = !active && (isPerson ? !person1Time : !person2Time);
console.log("fixed", fix);
I was able to fix the code to the desired result by wrapping the ternary evaluation in parentheses. What I am wondering is - why it works like this? The !active evaluates to false, and the ternary evaluates to true, and a console.log(true && false), this evaluates to false. Perhaps I am misunderstanding something here.
Boolean operators take precedence over ternary operators. In other words, this:
!active && isPerson ? !person1Time : !person2Time;
is equivalent to this:
(!active && isPerson) ? !person1Time : !person2Time;
Therefore, you obtain a different result.
Follow the operator precedence rules:
Binary AND (x && y) is priority 6.
Ternary (x ? y : z) is priority 4.
Unary NOT (!x) is priority 17.
Therfore, the NOT operator is evaluated first, then the binary AND, and lastly the ternary operator.
The original is evaluating the entire conditional expression on the left side of the ternary operator: !active && isPerson. Then based on the result of that expression - true or false - it evaluates the correct result.

Precedence If Clause Parenthesis and Equality [duplicate]

This question already has answers here:
Which Logic Operator Takes Precedence
(6 answers)
The order of operators in JavaScript (|| ,&&)
(4 answers)
Closed 3 years ago.
Parenthesis have higher precedence than equality.
So from my understanding, the higher precedence is evaluated first.
Lets now assume I compare a which is not defined:
if (a == 1) { .. // throws an exception because a is not defined
Actual case:
if (typeof a !== 'undefined' && (a == 1)) {
console.log(1)
} else {
console.log(2)
}
should be evaluated in this order:
(typeof a !== 'undefined' && (a == 1))
(a == 1)
typeof a
result from (3) !== 'undefined'
"result from (4)" && "result from (2)"
But this would usually throw an exception if a is not defined but it doesn't.
Why is the left side of the equation evaluated first even though it has the lower precedence?
EDIT: I adapted the example from '||' to && just because || would always throw.
|| is evaluated left-to-right:
5 Logical OR left-to-right … || …
So the inner expression that gets evaluated first is typeof a, as part of typeof a !== 'undefined'.
If the right-hand side of the || contains more expressions nested in parentheses, regardless of their operator precedence, they will only be evaluated after the left-hand side of the || has been evaluated.

if(a = 1) is true [duplicate]

This question already has answers here:
Variable assignment inside an 'if' condition in JavaScript
(6 answers)
Closed 6 years ago.
I don't know if it's possible duplicate. Testing my code, sometimes I was wrong with because I put = and not == or === in if conditions:
Consider this code :
var a = 0;
if(a = 1) console.log('true');
I don't know why this is not an error and why returns true the condition (a = 1)
I guess that what it does is assign 1 to the a variable, but why this evaluates to true and there's no error?
you're setting a to 1 and then checking the truthiness of the result. Non-zero numbers in JavaScript are true, so you get what you see.
Like in math, things are evaluated left-to-right, with parens going first.
As it was said, it does assign to your variable and will return true for all values other than 0.
A way to avoid these kind of mistakes is to change the test.
if( 3 == a)
Here if you ever write (3 = a) you would have an error.

var w = q||q2; what does this expression means? [duplicate]

This question already has answers here:
JavaScript || or operator with an undefined variable
(6 answers)
Closed 7 years ago.
what does this means?
var q = [];
var q2 = ["canada","usa","mexico"];
var w = q||q2;
document.writeln(w);
the value of the variable w is : [] the empty list.
can someone explain to me why it is displaying this [] instead of ["canada","usa","mexico"].
You should read Logical Operators from MDN. According to the documentation
The logical operator OR (||) 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; if both are false, returns false.
In a nutshell, logical operators evaluate from left to right. In your situation, since you have declare q as an empty array ([]), it evaluates to true and immediately goes and assigns w to that.
If you want q2 to take precedence, you can simply do
var w = q2 || q;
so that way only if q2 evaluates to falsey will it assign w to be q instead. The other option is to not declare q at all or declare it as something falsey. You can find out what evaluates to false here.

javascript ternary statement equivilance [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript: Is “z=(x||y)” same as “z=x?x:y” for non-boolean?
Are the following two lines of code equivalent in javascript?
a = b ? b : c
a = b || c
I want to express: "a should be assigned b if b is truthy, otherwise a should be assigned c"
I expect they would both work exactly the same, but I'm not 100% sure.
Yes. The two are almost exactly identical.
Both will first evaluate b. If it's truthy, it'll return b. Else, it'll return c.
As pointed out by #thesystem, if you have a getter method on b, it'll be called twice for the ternary, but only once for the or statement.
Test it using the following snippet:
var o = {};
o.__defineGetter__("b", function() {
console.log('ran');
return true;
});
var d = o.b || o.not;
console.log('-----');
var d = o.b ? o.b : o.not;
Here's the fiddle: http://jsfiddle.net/bqsey/
Logical operators are typically used with Boolean (logical) values;
when they are, they return a Boolean value. However, the && and ||
operators actually return the value of one of the specified operands,
so if these operators are used with non-Boolean values, they may
return a non-Boolean value.
ref: Logical Operators - MDN

Categories

Resources