Javascript usage of && operator instead of if condition - javascript

What's the point of having this logical operator like this: r == 0 && (r = i);?
function do()
{
var r = 0;
var i = 10;
r == 0 && (r = i);
}
is this the same as:
if (r==0)
{
r=i;
}

What always helps me is translating it to words
var r = 0;
var i = 10;
r == 0 && (r = i);
translates to
set variable r to zero
set variable i to ten
if variable r equals zero AND the return of the following statement "set variable r to value of variable i"
do nothing, but r is now 10.
so in short, let's forget about 1 and 2.
In javascript the execution flow in a boolean comparisan is to stop execution of if statement parameters if any part from the && fails.
An boolean comparisan will execute from left to right.
1 == 1 && 2 == 3 && (r = i)
it will pass 1 == 1 fail on 2 == 3 and never reach the assigment operation.
Basically it's a shorthand for:
if(r == 0) {
r = i;
}

Simple yes r == 0 && (r = i);is same as
if (r==0)
{
r=i;
}

Just tested the speed of the code and the && is little bit faster (almost negligible).
Coming to the actual question, I found the place of using && instead of if us literally short hand code of later. However I never use the code as it highly kill the readability of code reader.
As docs says
Logical operators are typically used with Boolean (logical) values. When they are, they return a Boolean value.
But what we are seeing here is an assignment to the a variable based on other. Of course the code works but I believe, this is just a mis usage of the convention.

It is the same, in terms of logic and control flow.
It is shortening lines of code (code golf) by (ab)using short-circuit behavior.
The StackExchange page for code golf is https://codegolf.stackexchange.com.
For even shorter code, you could use a logical OR as default operator.
r = r || i;
Or
r || (r = i);

I've been reading some of the answers here and I've come up with this summary.
Short Summary
Condition on r: Assign i to r, in case r is null:
r = r || i
Or
r || (r = i)
Condition on i: Assign i to r, in case i is not null:
i && (r = i)
Or
r = i || r
More Examples
a || (Do Something) // Means: if `a` is `null`
!a || (Do Something) // Means: if `a` is **not** `null`
a && (Do Something) // Means: if `a` is **not** `null`
!a && (Do Something) // Means: if `a` is `null`

It is indeed the same, and a technique often used by minifiers to collapse code. In this case, you can even use an ! in order to do the if as you are comparing without typecheck:
!r && (r = i);
Or use an || operator for this assignment:
r = r || i;
If you want to keep your code clear, use an if tho.

Consider you have something to print only when r=0 and i=10. then && will be use full like.
if(r==0 && i==10){
console.log('its good practice')
}
if we use seperate, like
if(r==0){
if(i==10){
console.log('its bad practice')
}
}
what will you do if you have lots of condition to check.? i suggest you to use first one.

Related

How does this code work as conditional statements, why aren't there any "if" or "else if" statements?

Given the following problem that I need to solve about nested logic, I saw the following possible solution online but I hadn't seen code organized like this and can't help to figure it out. It looks like a different approach I hadn't seen to "if" and "else if" statements, so I would like to understand what's going on. Thank you.
let fine = 0;
const [actual, expected] = input.split('\n').map(item => {
const [day, month, year] = item.split(' ').map(Number);
return {
day,
month,
year
};
});
(
actual.year === expected.year &&
actual.month === expected.month &&
actual.day > expected.day
) && (fine = (actual.day - expected.day) * 15);
(
actual.year === expected.year &&
actual.month > expected.month
) && (fine = (actual.month - expected.month) * 500);
(actual.year > expected.year) && (fine = 10000);
console.log(fine);
}
The code takes advantage of something called short-circuit evaluation, which isn't unique to JavaScript. In a broad sense, short-circuit evaluation means only evaluating a boolean expression if it is necessary to determine the ultimate outcome. It also takes advantage of the fact that in JS, assignment operators act as expressions.
Here's an example of what I mean:
let x;
console.log(x = 2) // 2
What this means is that you can have an assignment expression at the end of a list of conditions to act as an if statement. Due to short circuit evaluation, the assignment expression will only be evaluated if the ultimate true/false value of the full expression is not predetermined by the conditions.
let x;
(false && x = 1) // does nothing, false && ___ = false
(true || x = 2) // does nothing, true || ___ = true
(true && x = 3) // sets x = 3, true && ___ evaluates ___
(false || x = 4) // sets x = 4, false || ___ evaluates ___
JavaScript has short-circuit boolean evaluation, and the code in your question uses that extensively.
Take for example:
a() && b(); // if (a()) b();
Because both a() and b() need to evaluate to a truthy value for the entire statement to be considered true, JavaScript will not evaluate b() if a() already evaluates to a falsy value.
Similarly:
c() || d(); // if (!c()) d();
Because only one of c() or d() needs to evaluate to a truthy value for the entire statement to be considered true, JavaScript will not evaluate d() if c() already evaluates to a truthy value.
This can be used to implement logical branching, much like an if-else structure, although in most cases it does adversely impact the code's readability.
Nothing big changes in your code.
Heare simple syntax with the conditional operation in javascript var varname = condition ? true part code : false part code.
let fine = 0;
const [actual, expected] = input.split('\n').map(item => {
const [day, month, year] = item.split(' ').map(Number);
return { day, month, year };
});
fine = (actual.year === expected.year && actual.month === expected.month && actual.day > expected.day) ? ((actual.day - expected.day) * 15) : 0;
fine = (actual.year === expected.year && actual.month > expected.month) ? ((actual.month - expected.month) * 500) : 0;
fine = (actual.year > expected.year) ? 10000 : 0;
console.log(fine);
Something more

Dynamically constructed if statement in one string variable

I am blacking out over issue and I am convinced I am thinking too complex about this, but summarized, my issue is about this:
// imagine this variable is dynamically filled by a loop with conditions inside
var condition = varA + " == " + varB + " && " + varC + " == " + varD;
if (condition) {
// something
}
So it doesn't check whether varA equals varB and varC equals varD as what I intended, but instead it just sees it as a string and that appears to be always true anyway. I don't want, I want to see it actually checking whether varA equals varB etc.
Is there a way to parse this statement into something that actually can be a 'legit' if condition?
Thanks!
I think I understand what your trying to do. You are trying to look at a number of comparisons and determine, in the end, if all comparisons were truly true.
In this case you can actually just keep building your condition out as in the following:
var a = 1, b = 1, c = 3, d = 3, e = 5, f = 6;
var condition = a === b; // condition is true
condition = condition && c === d; // condition is still true
condition = condition && e === f; // condition is now and forever false
why not just do
if(varA == varB && varC ==varD){
//do something
}
edit
maybe try using safe-eval. its a third party package but APPEARS to be an improvement on eval.
The issue with your condition variable is that it's not checking for equality between your variables. The whole condition variable is being read as a string because it sees the == and && as strings and ends up concatenating them together.
I suggest writing your if statement like so:
if (varA === varB && varB === varC && varC === varD) {
// do something
}
That way, you're checking if varA is equal to varB and varB is equal to varC, etc. Using the triple equals also ensures that the variables are of the type value type (i.e. string, boolean, number). Hope this helps.

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

Lost in javascript comparisons

I'm writing a script to be executed when my body element hasn't got any of the following classes:
a OR b OR c AND d
I tried this, but it doesn't seem to do the trick:
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || ((!($('body').hasClass('c')) && (!$('body').hasClass('d'))))) {
}
UPDATE
This seems to work:
if (!($('body').hasClass('a') || $('body').hasClass('b') || $('body').hasClass('c') && $('body').hasClass('d'))) {
}
use
$(function(){
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || !($('body').hasClass('c') && $('body').hasClass('d'))) {
}
});
You are looking for a body that doesnt have any of the classes, so you need to use &&. Heres what happens:
if(hasclass(a) || hasclass(b)) = if(true OR false) = if(true)
Above the OR operator || means that once it hits a true evaluation, it will execute your if-block.
if(hasclass(a) && hasclass(b)) = if(true AND false) = if(false)
Here the AND operator && means that once you hit a false evaluation, you block won't be executed.
You want the last thing to happen, since you want it to have neither of the classes. Learn how to play with these operators as they can be very confusing. As long as you remember that the AND operator will execute only if all statements are true and the OR operator will only execute if one of the statements is true. Nested operators work the same, so if((a = b && b = c) || (a = c)) will execute if a,b and c are the same OR when a and c are the same, but not when a and b are the same or a and c are the same.
More on expression and operators (specifically Bitwise and a must read): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators

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.

Categories

Resources