JS && precedence vs === - javascript

According to javascript documentation, the === operator is higher precedence than && operator. Therefore, I would expect an expression like
false && undefined.foo() === undefined.foo()
to throw an error while evaluating either one of undefined.foo() calls. However, as I've tried in node, chrome, and firefox, the js engine always short circuits and returns false e.g.
> false && undefined.foo() === undefined.foo()
false
Shouldn't && short circuit kick in after === operands have been evaluated?

The higher precedence merely means that both operands undefined.foo() are associated with the === operator first before the operands for && are decided. It does not dictate the order of execution, which is still left to right.
Operator precedence merely decides whether the expression is evaluated as
(false && undefined.foo()) === undefined.foo()
or
false && (undefined.foo() === undefined.foo())
In either case false is still the first thing that's being evaluated; though if && had the higher precedence (first parenthesised example) then the 2nd undefined expression would always be evaluated too.

To better visualize why the precedence is being parsed the way it is, add in optional parenthesis according to how the interpreter ranks precedence:
( (false) && ( undefined.foo() === undefined.foo() ) )
Because === has higher precedence than &&, parenthesis gets added around the undefined.foo() === undefined.foo() expression first. Since precedence has now been determined, JavaScript interpreters will now parse it from left to right. Due to short-circuit evaluation, the undefined.foo() comparison expression never gets evaluated since the condition exits upon evaluating the false

Related

is && in short circuit logic the same as in if clauses?

Does the logical and operator (&&) or the logical or operator (||) have the same function in an 'if clause' as in it does in short circuit logic?
For example, && in short circuit should return the first falsey value, otherwise the last value if none is found: eg 0 && 1 returns 1. But if thats the case, how can it work in an if clause?
if (false && 1)
wont run because both conditions aren't true, yet short circuit seems to dictate that it will return 1, in which case 1 is a truthy value and the if clause should pass?
Edit: My mistake, I mixed up && and || in short circuit. They work the same as conditionals
&& in short circuit should return the first falsey value, otherwise the last value if none is found
Correct.
eg 0 && 1 returns 1
Nope. 0 && 1 returns the first falsey value, which is 0.
if (false && 1) wont run because both conditions aren't true
Correct. false && 1 returns the first falsey value, which is false. Since false is falsey, the if-statement doesn't run.
yet short circuit seems to dictate that it will return 1, in which case 1 is a truthy value and the if clause should pass?
Nope. As you said, it returns the first falsey value, which is false. The value of any of the later terms doesn't matter: if(false && something_that_crashes_the_browser()) works just as well.
Short circuit logic works the same as if-statement logic — there's really no difference, they're just conditionals:
console.log(0 && 1);
if (0 && 1) console.log("0 && 1");
console.log(false && 1);
if (false && 1) console.log("false && 1");

Please what does mean this : if (a && b == c){};?

Please what does mean this:
if (a && b == c){};
I did not understand the logic of the condition statement
&& has lower precedence than ==, so it's equivalent to:
if (a && (b == c))
It means if a has a truthy value and also the value of b is equal to the value of c.
The condition (a && b == c) has two operators. The Logical AND Operator and the Equality Operator.
The operation foo && bar returns true, if both operands foo and bar have truthy values.
foo == bar returns true, if foo equals bar.
The equality operator converts the operands if they are not of the same type, then applies strict comparison. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
If an expression contains more than one operator, the operator precedence is of the utmost importance.
Operator precedence determines the way in which operators are parsed with respect to each other. Operators with higher precedence become the operands of operators with lower precedence.
The == operator has a higher prededence than the && operator. Therefor the above condition will check b == c first. If the result is true and the value of a is truthy, the result of the condition will be true.
The Grouping operator ( ) has the highest precedence and therefor can be used to force a specific order of operations.
If you're not absolutely sure in which order operations will be processed, use the grouping operator!
The result of
(a && (b == c))
will be the same as the result of
(a && b == c)
but is better readable. Of course you should learn and know the precedence of operators. But if in doubt and especially in a really hairy line with lots of operators, the value that a few brackets add to readability can easlily outperform the costs of a few bits of additional code.

Why does this set of logical operators work correctly?

So I'm doing a puzzle to evaluate Kaprekar's Routine and in the first section I need to check to make sure the 4 digit input has at least two unique digits so I did this:
let numArr = num.toString().split("");
if (numArr[0] == numArr[1] && numArr[2] && numArr[3]) {
return 0;
}
I tried searching but I keep finding links to short-circuiting operators. I was expecting to write out numArr[0] == into every && block but to my surprise it worked. Can anyone explain why this returns 0 for 3333 but does not for 1234? I assumed numArr[2] and numArr[3] would just evaluate to true automatically.
There is a thing called operator precedence. The operator with higher precedence happens first. == happens before &&. When you have more than one operator of the same precedence it goes by 'associativity' which is generally left to right (= for example is right to left); so let's take another look at your code
if ( ((numArr[0] == numArr[1]) && numArr[2]) && numArr[3] )
Let's take just the first piece. Doing 3 == 3 is true and since none of the operators are 0, the if statement is true. But with 1234, 1 == 2 is false, so the expression short circuits to false. Generally when something (like an if statement) accepts a boolean value && a non zero/undefined/false value, the expression is considered true (I may be wrong). If you do the below you should get true
if ( numArr[0] && numArr[1] && numArr[2] && numArr[3] )
To answer your other question, generally when people work with a set of data in JS they use lodash. You can find the if there is 2 unique values easily with the line blow. uniq(array, func) returns an array with unique values in the same order. See the documentation
_.uniq("3333".toString().split(""), v=>v).length >= 2 //false
_.uniq("1224".toString().split(""), v=>v).length >= 2 //true
It is because
For String 3333
num[0] is 3,num[1]=3,num[2]=3,num[3]=3
Expressions evaluate based on precedence of operators
and when the operators have the same precedence they get executed from left to right
In this case == has highest precedence over &&
so,
num[0]==num[1] ,it is 3==3 true
then
true && num[2] && num[3] => true&&3&&3 => true
For string 1234
num[0]=1,num[1]=2,num[2]=3,num[3]=4
num[0]==num[1] ,1==2 is false
so now the expression is
false && num[2] && num[3]
For && operator if the first operand is false,it ignore the rest of the expression
so now it just results as false
Hope this helps
You have three expressions being evaluated
// loose-equality, so true if after type-coersion, the values are equivalent
// this is the only condition that is actually changing in your code, unless
// you have a number with less than 4 digits
numArr[0] == numArr[1]
// is a non-empty string so it's 'truthy'
numArr[2]
// is a non-empty string so it's 'truthy'
numArr[3]
Anything that is not Falsy (false, 0, "", null, undefined, and NaN) is Truthy
Therefore, you need to write additional code to check for unique digits.

What is the meaning of || in javascript?

I am looking at these lines of code from here:
if (callback)
callback(sig || graph);
I have never see vertical "or" bars in a javascript method call. What do they mean? Do they pass the "true" parameter (i.e. sig or graph)? Do they pass the defined parameter? I have never seen that syntax before.
This is the logical OR operator in JS (and most other languages). It is defined in the spec at 11.11. As noted in the spec, expressions on either side will be evaluated first and the logical OR is left-to-right associative. Note that evaluation of the operands follows standard ToBoolean semantics from section 9.2, so [null, undefined, 0, ''] all count as falsy.
Unlike most languages, JS returns the left operand if it is truthy or the right operand otherwise. This behavior has been covered before in a number of SO questions, but is worth noting as most languages simply return true or false. This behavior is often used to provide default values to otherwise undefined variables.
The Logical OR operator (||) is an operator that returns its first or second operand depending on whether the first is truthy. A "truthy" value means anything other than 0, undefined, null, "", or false.
This operator uses short-circuiting, meaning if the first expression is truthy, then the second expression is not evaluated and the first operand is returned immediately. This is akin to the Logical AND operator (&&), which does the opposite: if the first operand is falsey, it returns it, otherwise it returns the second expression.
It means 'or' (http://www.w3schools.com/js/js_comparisons.asp) So if(sig OR graph)
BE CAREFUL you can 'short circuit' your code using this.
example :
If (foo || foo2)
if foo is true, then JavaScript wont even test foo2 at all, it just skips it.
It passes whichever evaluates as true, or sig if both are true.
The double pipe (||) represents OR in JS. In simple words, either this or that is True. It requires any of the sides true to get a True result.
For example:
var x = 8;
var y = 'c';
x >= 8 || y === 'a'
The left side of the double pipe returns True where the right side is False. Thus, the result is True.
The operator || means OR.
If either sig or graph are true or not null variables, callback function will receive a true argument.

In JavaScript, why does (undefined && true) return undefined? [duplicate]

This question already has answers here:
Javascript AND operator within assignment
(7 answers)
Closed 8 years ago.
Using the node.js console (node 0.10.24)
> var x = (undefined && true);
undefined
> x;
undefined
> x = (true && undefined);
undefined
> x;
undefined
Why does the comparison return undefined? I would expect it to return false since undefined is considered "falsey".
The && operator proceeds by internally coercing the values of the expressions to boolean, but the result of the operator is always the actual, uncoerced value of the first expression that failed (i.e., that was falsey).
Thus (true && undefined) will result in undefined because true is not falsey. Similarly, (true && 0) would evaluate to 0.
In javascript || and && are not guaranteed to return boolean values, and will only do so when the operands are booleans.
a = b || c is essentially a shortcut for:
a = b ? b : c;
a = b && c is essentially a shortcut for:
a = b ? c : b;
//or
a = !b ? b : c;
To formalize what others are saying, here's what the ECMAScript specification says about how the logical AND operator is evaluated:
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).
And perhaps most relevant, the note at the bottom of section 11.11:
The value produced by a && or || operator is not necessarily of type
Boolean. The value produced will always be the value of one of the two
operand expressions.
The other answers are more than adequate, I'm including my answer here for posterity just in case someone else's brain works like mine:
The result of the boolean || and boolean && operators will always be the result of the last expression evaluated, taking into consideration short circuiting.
So, for ||, if the first expression is truthy, short circuit evaluation means that the rest is ignored, and the result will be the value of that first expression. If it's falsy, evaluation must continue to the second expression, and the result will be the result of that second expression no matter whether it's truthy or falsy.
Likewise for &&, if the first expression is falsy then evaluation stops and the result is the result of that first expression, if it's truthy then evaluation continues and the result is the result of the second expression.

Categories