a && b && c VS if - What's the difference on performance? - javascript

Just saw a line of code: a && b && c. I think this should be equivalent to if(a && b) {c}. But I'm really curious that is there any performance difference on these code, or it's just simply cool to put it in one line?
This is actual code: sourcesPanel && sourcesPanel.tips && sourcesPanel.tips.clearTimers()
The sourcesPanel and sourcesPanel.tips are two objects in the program.
Basically, I think it's checking if those two objects exist, it they exist, call that clearTimers function.

The logical operators in JS have a very important behavior: they return the first conclusively failing or succeeding operand. If does not.
The behavior of if (a) { if (b) { ... is pretty simple: if they are truthy, enter the block.
The behavior of && is different:
foo = 1 && 2 && 3; // foo = 3, succeeds all the way through
foo = 1 && 0 && 3; // foo = 0, failed at 0
foo = 1 && null && 3; // foo = null, failed at null
When the logical operators are used within an if, the behavior appears to be exactly the same. Used on their own or with an assignment, they behave in a relatively unexpected way.
Take the use of || to provide defaults:
opt = opt || {foo: bar};
If opt was truthy (for an object, present) use it, otherwise use the defaults. The other logical operators behave the same way.

That is actually a double check and not a simple conditional check like you sugest: if(a && b) {c}.
The equivalent to a && b && c would be:
if (a && b){
if(c){
// do something
So all a, b and c have to be truthy.
a && b && c is mostly more practical than doing
if (a){
if (b){
if(c){
// do something
But in a triple check like a && b && c b will never be evaluated if a evaluates false. Thus sparing time. The same for c that will only be evaluated if a and b also were true.

There is a performance improvement in some circumstances.
The line is executed step by step from left to right, and leaves as soon as it fails.
So, if a is false, b and c will not be evaluated.
You see this a lot in bash where one instruction is dependent upon another succeeding, but the first has to be attempted no matter what.

Related

In what situation would 'a != a' resolve to true in JavaScript?

Looking through the code of svelte.js I found this odd looking function:
function not_equal(a, b) {
return a != a ? b == b : a !== b;
}
Can someone explain to me in what situation comparing a variable with it self for inequality would resolve to false?
I know that != and == are weaker comparison operators than !== and === because they don't really care about the type but I still can't figure out what makes the not_equal function different from a simple a !== b
There are a couple of ways:
1. If a is NaN: NaN is not equal to anything, including itself.
let a = NaN;
console.log(a != a); // true
I think this is the likely reason for that conditional operator in not_equal, since with that function not_equal(NaN, NaN) is false (e.g., it considers NaN equal to itself). It's not clear to me why they went with the == rather than === in b == b, though.
2. (This doesn't apply to your function, just the a != a question.) If a is a property with a getter function that returns a different value when called twice in succession (because it returns a random value, or a value that changes over time, or the getter mutates the value, etc.) being used within a with statement (very unlikely), or similar using a Proxy rather than a with.
const obj = {
get a() {
return Math.random();
}
};
with (obj) {
console.log(a != a); // PROBABLY true
}
(Note: There are very good reasons not to use with, and it can't be used in strict mode.)
Other than that, I can't think of a way a != a would be true.

How can I evaluate the value of multiple variables in an If Statement using AND and OR in JavaScript

First off, I am not a pro developer (yet), and hope someone could perhaps give me some input on a subject that seams easy, but it's not so easy.
How can I evaluate the value of multiple variables in a single IF statement?
This is something that still makes me scratch my head. I have seen others use it, but it is as if I am missing out on something. I have read an article about it, and looked at a logical operator app. Still frying my brain though.
Example: (Pseudo Code) if A is not B and A is not C, do something.
if(A !== B && A !== C) {
// Do Something
}
or
if(A !== B || A !== C) {
// Do Something
}
Which do I use? or is the answer perhaps NONE?
The code within the brackets will execute if the condition evaluates to true (or any loosely typed truthy value).
Consider A = 1; B = 2; C = 1;
(A !== B && A !== C) will evaluate to (true && false), which will evaluate to (false) (both conditions are not met).
(A !== B || A !== C) will (short circuiting aside) evaluate to (true || false), which will in turn evaluate to (true) (one of the conditions is met).

How to infer "config.headers = config.headers || {};"

I don't get operation process of the below statement.
var x = x || {};
I think that what it does is
IF x exists, assign it to var x, if not assign null. "undefined || null?"
why do we need the later " || null " part?
A link to lessons or little help would be grrreat!
null and undefined don't enter into this anywhere.
All this does is set x to the value {} if x is a "falsy" value. {} is an empty object literal.
You probably know || and && as OR and AND in conditions. They work by "short circuit evaluation", meaning || will stop evaluating and return the last expression as soon as any of the expressions (starting from the very left) evaluates to true. (In other words: Since only one expression is required to be true for the whole compound to evaluate to true, we may stop as soon as any of them is true.) On the other hand && stops evaluating as soon as any of the expression is evaluating to false (so the whole compound can't be true as soon as any of its parts is false). In other words, && will continue evaluating the terms as long as they are true and || as long as the terms are false.
Now, we may not only use these operators in conditions, but anywhere in the code. For example a && b(); is equivalent to the if-clause if (a) b();. Similarly, || may be used for "is not": a || b(); is equivalent to if (!a) b();.
Since || returns the value of the first term from the left that evaluates to true, we may use this on the righthand-side in order to assign a default value (in case that the previous term(s) would evaluate to false):
a = b || c;
is equivalent to
if (b) {
a = b;
}
else {
a = c;
}
We may do this with any number of terms:
var api = window.webAPI || window.webkitWebAPI || window.mozWebAPI;
(This would evaluate to the hypothetical "window.webAPI", or, if undefined, look for the "webkitWebAPI" and then for the "mozWebAPI".)
In the case of var x = x || {}; the construct just makes sure that x is something (apparently something object-like), and if not, makes it an empty object ({}).
It is equivalent to the if-clause
var x;
if (!x) x = {};
So, why would we use this? Obviously, when first encountered, it initializes variable x to an empty object. But it does this conditionally: If x would have been set before, it preserves the value of x. Also, since we declare x as a variable in the same clause, we make sure that we do not hit an undeclared identifier (saving an extra declaration on another line).

meaning of the AND operator in this line

What is the meaning of && in this JavaScript code?
function doIt(a) {
var b = a.parents(),
c = 1;
return b.each(function() {
jQuery(this).hasClass("free-content") && (c = 0)
}), c
}
normally I would think this would be a logical operator AND, but I can't figure out what it does in this line.
The logical AND operator in this case is used in place of an IF-statement. It will set c to 0 if jQuery(this).hasClass("free-content") returns a truthy value.
It's equivalent to:
if (jQuery(this).hasClass("free-content")) {
c = 0;
}
You wondering what it means is actually the reason I dislike this type of coding and consider it a bad practice. It's hard to read and can create confusion, which in turn can create bugs.
It's also worth noting what logical AND returns, if you want to use the returned value:
(Logical AND) Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
Here's an example showing, in my opinion, bad code since it's hard to follow:
var foo = bar && baz || qux;
The above code is equivalent to:
var foo;
if (bar && baz) {
foo = baz;
} else {
foo = qux;
}
Summary: Do not use logical operators as a nifty way to replace IF-statements or to save keystrokes. It will most likely come back and bite you or someone else in the ass.
I know there will be people arguing against me on this (usually the same people who doesn't want to use semicolon because ASI), but it's just a really bad idea to write code that only an expert would understand. There's no argument against it.
return b.each(function () {
jQuery(this).hasClass("free-content") && (c = 0)
}), c
b.each loops over all entries in b, and checks whether the current element has the class free-content set. Only if that yields true, the second part of the expression is evaluated – because they are concatenated via &&, and JavaScript stops evaluating such an expression when the first part is false, because then the whole expression can’t become true any more.
So if there is an element with that class, the second part is evaluated – and thereby c is set to the value 0 (because that’s the assignment operator = there, and not a comparison).
And after that each loop is finished, the value of c is returned to the outside – because each() and c are connected via the comma operator , here, which evaluates its operands from left to right and then “returns” the second one.
JavaScript allows a lot of “fancy” coding like this, but as Marcus already said in his answer, that is hard to read, and there is no actual advantage here over, say
b.each(function() {
if(jQuery(this).hasClass("free-content")) {
c = 0;
return false;
}
});
return c;
I added the return false here inside the each loop, because once we found an element with that class, we don’t need to search the rest of them any more – that’s something that the person who came up with the original code forgot to do in all their “fancy-ness” … their loop will continue to iterate over all of b’s elements, not matter if it finds the element it is looking for in the first round already.

Does a javascript if statement with multiple conditions test all of them?

In javascript, when using an if statement with multiple conditions to test for, does javascript test them all regardless, or will it bail before testing them all if it's already false?
For example:
a = 1
b = 2
c = 1
if (a==1 && b==1 && c==1)
Will javascript test for all 3 of those conditions or, after seeing that b does not equal 1, and is therefore false, will it exit the statement?
I ask from a performance standpoint. If, for instance, I'm testing 3 complex jQuery selectors I'd rather not have jQuery traverse the DOM 3 times if it's obvious via the first one that it's going to return FALSE. (In which case it'd make more sense to nest 3 if statements).
ADDENDUM: More of a curiosity, what is the proper term for this? I notice that many of you use the term 'short circuit'. Also, do some languages do this and others dont?
The && operator "short-circuits" - that is, if the left condition is false, it doesn't bother evaluating the right one.
Similarly, the || operator short-circuits if the left condition is true.
EDIT: Though, you shouldn't worry about performance until you've benchmarked and determined that it's a problem. Premature micro-optimization is the bane of maintainability.
From a performance standpoint, this is not a micro-optimization.
If we have 3 Boolean variables, a, b, c that is a micro-optimization.
If we call 3 functions that return Boolean variables, each function may take a long time, and not only is it important to know this short circuits, but in what order. For example:
if (takesSeconds() && takesMinutes())
is much better than
if (takesMinutes() && takesSeconds())
if both are equally likely to return false.
That's why you can do in javascript code like
var x = x || 2;
Which would mean that if x is undefined or otherwise 'false' then the default value is 2.
In case someone's wondering if there is a way to force the evaluation of all condition, in some cases the bitwise operators & and | can be used
var testOr = true | alert(""); //alert pops up
var testAnd = false & alert(""); //alert pops up
These should be used really carefully because bitwise operators are arithmetic operators that works on single bits of their operand and can't always function as "non short-circuit" version of && and ||
Example:
-2147483648 && 1 = 1
but
-2147483648 & 1 = 0
Hope it helps someone who arrived here looking for information like this (like me) and thanks to #Max for the correction and the counter-example
It will only test all the conditions if the first ones are true, test it for yourself:
javascript: alert (false && alert("A") && false);
It short circuits - only a and b will be compared in your example.
Another reason why stopping evaluation with 1 or more parameters to the left.
if (response.authResponse && (response.authResponse.accessToken != user.accessToken)){
...
}
the second evaluation relies on the first being true and won't throw a compile error if response.authResponse is null or undefined etc because the first condition failed.
Other languages had this problem in the early days and I think it's a standard approach in building compilers now.
It exits after seeing that b does not equal one.
For anyone on this question confused because they're not seeing the short-circuit behaviour when using an || in conjunction with an ? operator like so:
x = 1 || true ? 2 : 3 // value of x will be 2, rather than 1 as expected
it seems like the short circuit rule isn't working. Why is it evaluating the second term of the || (true ? 2 : 3) when the first is true? It turns out to be an order of operations problem because the above is the equivalent of
x = (1 || true) ? 2 : 3
with the || evaluated first and the ? evaluated second. What you likely want is:
x = 1 || (true ? 2 : 3)
For this case:
a = 1
b = 2
c = 1
if (a==1 && b==1 && c==1)
You can use:
if ([a, b, c].every(x => x == 1))
// do something if a, b and c are equal to 1.
If you want to know if at least one is equal to 1, use the some() method instead of every():
if ([a, b, c].some(x => x == 1))
// do something if a, b or c is equal to 1.
every() and some() are array methods.

Categories