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.
Related
This question already has answers here:
What's the difference between & and && in JavaScript?
(4 answers)
Closed 3 years ago.
I have two conditions that validate if "a" equals zero and "b" less than 5, both behave in the same way, but with different operators, is there any real difference between them?
var a = 0;
var b = 3;
if (!a & (b < 5)) {
}
if (!a && b < 5) {
}
The key difference is that the & operator is a bitwise operator, while the && operator is a logical operator.
Bitwise operators work on bits and perform "bit by bit" operations, they are applied to the bits of one or two operands. The & represents a bitwise AND operation- where A and B represent two inputs; both inputs must be true in order for C to be true.
So for instance in the example you provided you have:
if(0 & 1){
}
The result of the bitwise AND on 0 and 1 as inputs is 0 (false) because both inputs must be true for the output to be true.
The && operator is a logical operator, which is used to make a decision based on multiple conditions. It can apply to one or two operands each of which may be true or false.
if (!a && b < 5) {
}
The above still evaluates to false because both conditions must be met for the code inside the if statement to be executed. In addition to this, using the && operator will (depending on the language) short circuit, which means that the second condition of the if will only be evaluated if the outcome is not determined by the first condition.
So this expression will fail as soon as a is found to be zero (false) because there is no point in evaluating the second expression as the first expression had to be true. This is another difference as the bitwise & operator does not short circuit.
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.
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
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.
I came across the following and was unable to grasp the reason, can anyone explain please?
var foo = [0];
console.log(foo == !foo); // true
console.log(foo == foo); // true
The second comparison is simple to explain: foo is equal to itself.
The first one, however, is a bit tricky: foo is an array, which is an object, which evaluates to true when coerced to boolean. So !foo is false. But foo on the left side of the comparison is not being converted to boolean. Both operands are actually converted to numbers during the equality comparison. This is how it evaluates:
[0] == false
[0] == 0
"0" == 0
0 == 0
true
According to MDN, on comparisons with the equality operator ==:
If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible
I know this explanation sounds superficial. It's actually much more complicated than that, but the basic steps are the ones I listed above. You can see the details on the ECMA-262 specification, particularly on sections 9 and 11.9.
You should use "===" and "!==" instead of "==" and "!="
More explanations there:
Which equals operator (== vs ===) should be used in JavaScript comparisons?
http://net.tutsplus.com/tutorials/javascript-ajax/the-10-javascript-mistakes-youre-making/