Variable assignment inside an 'if' condition in JavaScript - javascript

How does the below code execute?
if(a=2 && (b=8))
{
console.log(a)
}
OUTPUT
a=8

It has nothing to do with the if statement, but:
if(a=2 && (b=8))
Here the last one, (b=8), actually returns 8 as assigning always returns the assigned value, so it's the same as writing
a = 2 && 8;
And 2 && 8 returns 8, as 2 is truthy, so it's the same as writing a = 8.

It's generally a bad idea to do variable assignment inside of an if statement like that. However, in this particular case you're essentially doing this:
if(a = (2 && (b = 8)));
The (b = 8) part returns 8, so we can rewrite it as:
if(a = (2 && 8))
The && operator returns the value of the right hand side if the left hand side is considered true, so 2 && 8 returns 8, so we can rewrite again as:
if(a = 8)

It is called operator precedence
(a=2 && (b=8))
In the above example. then results are evaluated against the main && sign.
(a=2 && (b=8)) evaluated to a = 2 && 8
So 2 && 8 return a = 8

You're setting (not comparing) a to 2 && (b=8). Since 2 is tru-ish the second half of the expression will be executed, i.e. a = true && (b = 8), i.e. a = (b = 8), i.e. a = 8.

Your statement is interpreted like
a = (2 && (b=8))
when you uses && statement, then last true statement value will be returned. Here (b=8) will becomes value 8 which is true and last statement.

To understand what is going on, refer to the operator precedence and associativity chart. The expression a = 2 && (b = 8) is evaluated as follows:
&& operator is evaluated before = since it has higher priority
the left hand expression 2 is evaluated which is truthy
the right hand expression b = 8 is evaluated (b becomes 8 and 8 is returned)
8 is returned
a = 8 is evaluated (a becomes 8 and 8 is returned)
Finally, the if clause is tested for 8.
Note that 2 does not play any role in this example. However, if we use some falsy value then the result will be entirely different. In that case a will contain that falsy value and b will remain untouched.

Related

Oddity with using || for assignment where Conditional (ternary) operator is second option

Caught a bug in my code, where I'm using foo = bar || baz to assign to baz if bar is undefined, however when using a ternary expression for the second argument, JS would assign the true value for the ternary expression, regardless of the first value.
Opened up the console and tested it. Seems that JS doesn't even evaluate the conditional expression, as seen here, where b isn't defined, but it still returns the true value for it.
>>> a = 1 || 2
1
>>> a = 0 || 2
2
>>> a = 1 || b
1
>>> a = 1 || b ? 3 : 4
3
>>> b
ReferenceError: b is not defined[Learn More]
>>> a = 1 || ( b ? 3 : 4 )
1
I am able to get the correct result by wrapping the ternary expression in ()s, but what's going on here? Why does it return 3 in the above test-case?
|| is lazy - it will not attempt to evaluate the right-hand side of a || of the left-hand side is determined to be truthy. If you had done b || 1 instead of 1 || b, it would have tried to evaluate b first, and an error would be thrown:
const a = b || 1 ? 3 : 4
The whole left side of the ? is interpreted to be the condition. (Other operations performed on the left of a ? will also be parsed before the whole ? condition is evaluated.) The conditional operator has one of the lowest operator precedences.
For
1 || b ? 3 : 4
the operator with the highest precedence there is ||, at 5. So the two expressions across from the || get evaluated for "or" first:
1 || b
Since 1 is truthy, the whole 1 || b evaluates to 1 without considering b.
1 ? 3 : 4
Then the conditional operator is evaluated (precedence 4):
true ? 3 : 4
evaluates to
3
because the condition is true.
When you put parentheses around the conditional:
1 || ( b ? 3 : 4 )
Parentheses have the highest operator precedence, at 20 - the interpreter knows that everything inside the parentheses will evaluate to a single expression, without regard to what's outside the parentheses. So
1 || <something>
evaluates to
1
because 1 is truthy.

Javascript simplified if-statement

I'm scratching my head trying to understand this very simplified if statement. When searching for the answer, all I find is answers related to ternary operators.
Anyway. Why is it that the first case below works, while the latter throws an ReferenceError? Just trying to understand how things work.
true && alert("test")
var x;
true && x = 10;
This has to do with operator precedence. As the && operation is computed before the =, your second example would end up making no sense : (true && x) = 10;
For your second case to work, add parenthesis this way :
var x;
true && (x = 10);
Javascript seems to give higher precedence to && than to the assignment operator. The second line you gave is parsed as:
(true && x) = 10;
If you add parenthesis around the assignment, I think you will see the behavior that you were expecting:
true && (x = 10); // Sets x to 10 and the whole expression evaluates to 10.
And just in case you needed a pointer as to why && can be used as an if-statement, the phrase "short-circuit evaluation" might help.
It'a Operator precedence.
As you can see && has higher priority than =
So true && x = 10; is actually (true && x) = 10; which is clearly wrong. You can only assign value to variables, and (true && x) is either false or the value of x.
The result of alert() is undefined. So first example could be retyped as:
var x; // x is now 'undefined'
true && x; // true and undefined is undefined
The second example is about operators priorities. Runtime evaluate expression as (true && x) = 10;
var x;
true && (x = 10); // result will be 10

javascript or operation returns unexpected result

I am very new to javascript. I have a programm like:
var a = 2
if(a !=2 || a != 3){
console.log("not")
}
Here I have set the variable a value to 2.
In my condition I have set if a is not 2 or a is not 3 it should print not
But here a's value being 2 it is printing not.
It always give not whatever the value is
I can check this is python easily like:
if not a == 2 or not a== 3
Whats wrong in here ??
var a = 2
a is now 2.
a !=2
This is false, so we look on the other side of the or
a != 3
This is true. So one of the two sides of the or test is true. Therefore the or test is true.
If you want to test if a value is not 2 and it is also not 3, then you need to use an && operator.
Maybe you want this:
if(a !=2 && a != 3){
console.log("not")
}
In other words, if a is not 2 AND a is not 3.
This is just how boolean logic works. In your example, because a does not equal 3, the condition is true.
Please read how logical operators work.
Your condition evaluates to true if a is not 2 or a is not 3, that means that is will be false only when a is both 2 and 3 at the same time which isn't possible - this condition will always be true.
You might be also interested in reading something on mathematical logic and negations.
If you want to ensure that a is not 2 or 3 then you should change it to
if((a != 2) && (a != 3)){
as in a is not 2 and a is not 3 - keep in mind that you are working with 2 statements.
Simple explanation
false || true = true
a != 2 //returns false
a != 3 //returns true
In python:
not a == 2 // returns false
not a == 3 //returns true
"OR" in the condition means that the statement in the if block will get executed if any one of the equations out of
(a != 2)
and
(a != 3)
returns true.
In your code snippet
(a != 3)
is true and hence the statement
console.log("not");
gets executed.
This is very expected behaviour and it work same in python and javascript
a = 2
if not a == 2 or not a== 3:
print ("not")
is equivalent to
var a = 2
if(a !=2 || a != 3){
console.log("not")
}
in or expression conditions check while one of theme be come true or until there was no condition.

What does "|| 0" do in JavaScript? [duplicate]

This question already has answers here:
What does the || operator do?
(4 answers)
What does "options = options || {}" mean in Javascript? [duplicate]
(5 answers)
Closed 8 years ago.
I have a piece of JavaScript code that shows:
function(next, feather) {
var l = Number(171) + (next || 0);
var m = Math.max(1, l - 9);
return {
lc: 300 * (l + 1) * m + (5 * feather || 0)
}
}
Now I've simplified it a little bit. But can anyone explain what the "|| 0" does? As far as I can tell it does nothing.
(Notice I replaced a function with Number(171), as that function effectively returns a number, feather is also supposed to be a number, 0 most of the time, 1 sometimes).
If next is falsy, 0 will be used in its place. JavaScript has no default value operator, so users have leveraged this approach, even though the language's creator has called it an abusage.
Well if you know next and feather are numbers, then yes, it has no function. However, if you were to pass in a value like undefined, which is effectively what will happen if you call the function without specifying any parameters, you'll see some difference:
var next = undefined;
console.log(171 + next); // NaN
console.log(171 + (next || 0)); // 171
Of course, this isn't a foolproof method. Passing in null has no effect on the computation, and passing a non-empty string (e.g. "1"), will result in something very different.
variable || 0 looks up the variable, and if it is undefined, null, or empty (i.e. zero), it will use the number 0 instead. This actually makes sense because if it was anything other than zero itself, it would return NaN.
If that didn't make any sense, this should:
undefined * 1 == NaN;
(undefined || 0) * 1 == 0;
If the next is falsy (false-like value) zero is used instead.
E.g.
next || 0
equals something like
if(!next) { return 0 } else { return next; }
It forces false-like values to be an actual zero number.
If the context before the logical or || is falsy (this includes nulls and undefineds), then it will take the value after it. So in your case, if next or feather is not defined or 0, then the value of 0 will be used in those calculations within the parenthesis, essentially the code will read as the following if both are 0 or undefined:
function(next, feather) {
var l = Number(171) + 0;
var m = Math.max(1, l - 9);
return {
lc: 300 * (l + 1) * m + 0
}
}
Using the OR operator || in this scenario is basically short hand for checking weather or not next was included. If it were coming from some sort of number calculation, perhaps it was possible that next was NaN at times (which is always falsy) and so this was the workaround to make it 0.
var l = Number(171) + (next || 0);
A more readable approach would be to test for that case at the inset of the function
if( isNaN(next) )next = 0;
Or to also include other tests as well
if( isNaN(next) || next === null || typeof(next) === "undefined" )next = 0;
The && and || operators in JavaScript will shortcut evaluation. The way it's set up in the example you gave, if 'next' evaluates to a boolean TRUE then that will be added to 'l', otherwise '0' will be added.

Shorten JS if or statement [duplicate]

This question already has answers here:
How do I check if an array includes a value in JavaScript?
(60 answers)
Closed 6 years ago.
Is there anyway to shorten something like this in Javascript: if (x == 1 || x == 2 || x == 3 || x == 4) to something like if (x == (1 || 2 || 3 || 4)) ?
You can use use Array.indexOf
[1,2,3,4].indexOf(x) !== -1
You can also use objects as some kind of hash map:
//Note: Keys will be coerced to strings so
// don't use this method if you are looking for an object or if you need
// to distinguish the number 1 from the string "1"
my_values = {1:true, 2:true, 3:true, 'foo':true}
my_values.hasOwnProperty('foo')
By the way, in most cases you should usi the "===" strict equality operator instead of the == operator. Comparison using "==" may do lots of complicated type coercion and you can get surprising results sometimes.
If your cases are not that simple to be expressed by this:
if (1 <= x && x <= 4)
You could use an array and indexOf:
if ([1,2,3,4].indexOf(x) > -1)
Note that indexOf might need to be re-implemented.
Not without writing a function that takes an array as an input and returns true/false, or some sort of array search. It would be hard to maintain/other devs to read. And it would be significantly slower. So just stick with the semantically correct longer version.
Also a good way to see if anything can be shortened significantly is to run it through the close compiler and see what it comes out with.
How about:
if (x > 0 && x < 5) {
}
You could write a function:
function isAny(x) {
for (var i = 1; i < arguments.length; ++i)
if (arguments[i] === x) return true;
return false;
}
Then you can say:
if (isAny(x, 1, 2, 3, 4)) { /* ... */ }
(Whether to use "===" or "==" would depend on the exact semantics you want.)

Categories

Resources