This procedure has likely been covered on SO in some form but I do not know how to find it.
I would like to compare one value with two others and assign a variable ideally in the same step.
In my case, I have a user Id (A) and two sample user ids ( B and C )
Either B or C in this situation must be equal to A.
I want to check if A == B or A == C and then set a variable (other) to the B or C id that DOES NOT equal A.
I know I could do
if (A == B) {
var other = C;
return other
}
else {
var other = B
return other
}
Simple enough but does anyone know of a more efficient way? Any JS libraries are allowed.
You can do that with a ternary condition:
var other = A == B ? C : B;
In this case, if A and B are the same, other will be set to C, otherwise it'll be set to B.
Simple enough but does anyone know of a more efficient way?
You can use the if condition what you are using presently or you can use the ternary operator. Both are having the same performance. Its just the matter of readability to what you want to use. As far as performance is concerned both the ways are almost equally efficient.
Just saw this JSPerf test and found that if condition is faster than ternary condition.
Related
This question already has answers here:
What does the construct x = x || y mean?
(12 answers)
Closed 6 years ago.
In JavaScript I recently realized you could use the OR || logical operator for assignment, and I want to know if it's considered bad practice.
In particular I have some functions that have optional array input, if the input is null or undefined I should just set it to an empty array [], if it has content it should take the content.
I found that using the assignment using the OR operator handles that perfectly in a single line, it's clean. However, it feels like the kind of thing that might be considered bad practice, or may have some horrible pitfalls I'm not considering.
Another approach is a simple if check, which is fairly safe in general.
I want to know if using the || approach seen below has any pitfalls I'm not considering, although it works in this scenario I would appreciate knowing if it works well to keep using this in the future, or to stop using it altogether.
https://jsbin.com/nozuxiwawa/1/edit?js,console
var myArray = ['Some', 'Strings', 'Whatever'];
// Just assign using OR
var pathOne = function(maybeAnArray) {
var array = maybeAnArray || [];
console.log(array);
}
// Assign using IF
var pathTwo = function(maybeAnArray) {
var array = [];
// Covers null and undefined
if (maybeAnArray != null) {
array = maybeAnArray;
}
console.log(array);
}
console.log('Path one:');
pathOne(myArray); // ['Some', 'Strings', 'Whatever']
pathOne(null); // []
console.log('\nPath two:');
pathTwo(myArray); // ['Some', 'Strings', 'Whatever']
pathTwo(null); // []
IMHO the use of the OR || for the purposes of assignment is perfectly valid and is good practice. We certainly use it in our projects and I've seen it used in lots of 3rd party projects that we use.
The thing you need to be aware of is how certain JavaScript objects can be coerced to be other values. So for example, if you're ORing values such as "", false or 0 then they are treated as false... this means that when you have the following:
function f(o) {
var x = o || -1;
return x;
}
Calling:
f(0)
...will return -1... but calling
f(1)
Will return 1 ... even though in both cases you passed a number - because 0 is treated as false -1 is assigned to x.
...that said, as long as you're aware of how the OR operator will treat the operands that you use with it - then it is good JavaScript practice to use it.
i prefer the first option, it's clear for my eyes, but when i need to share my code with others will think about to use second, will be more clear for any.
Now i'm using sonar, and prefer the second option too, will more easy to comprend for machine in inegration works.
Last idea is to use
if(maybeAnArray !== void(0))
Two reasons:
use cast and type conditionals
void(0) will works same for all browsers
Expect it helps yopu
When given the option, I prefer concise code (which must still be readable).
I would say || is common enough that it is considered good practice. Once one has seen it a few times it reads just fine.
In my opinion there are few reasons why you should rather use the second option:
First of all it's much more readable - new developers that are still learning can have problems with understanding notation like var myArray = someArrayArg || [];
If you are using some kind of code checkers like JSLint, they will return warnings and/or errors like Expected a conditional expression and instead saw an assignment. for the statement with var myArray = someArrayArg || [];
We already have something like var myArray = someArrayArg ? someArrayArg : []; that works pretty well
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.
I'm sure this thing is duplicated somewhere but I don't know what to search.
So, I've been looking through a Node.JS Application and found this code and wondered what it does. I have tried searching but I don't know what to search so I was hoping someone would it explain it to me.
init = refresh = function () {
// code here..
};
I understand 1 equals, but why 2? does it make some sort of alias so that function can be run with both init and refresh?
= resolves the right hand side and then assigns the result to the left hand side.
The result of doing this is the same as the result assigned.
So that assigns the function to both init and refresh
Quentin did a very good job telling you what it is doing.
I just wanted to chime in to give an example where you might use this:
Say for instance you have an object:
var obj = {
init: function() {
var x = this.x = [1,2,3];
}
};
What this allows you to do is reference your x variable two different ways (either through x or this.x).
Now why would you do this?
Well two major reasons.
It is faster to access x rather than this.x (but you still need to access it elsewhere)
It produces easier to read code when having to read/write to x lots of times in one function.
This is just another reason why you would use it.
But in most cases it is just aliases, such as: forEach -> each
Here's an explanation using operator associativity and precedence.
So, looking at an operator precedence description from Mozilla, when an expression includes multiple operators of the same precedence, as in
a OP b OP c
, then you check whether that level of precedence uses right-to-left or left-to-right associativity.
a = b = c
The assignment operator in JavaScript is the only operator on its level of precedence.
It has right-to-left associativity
So in a = b = c, b = c is evaluated first, assigning the value of c to b.
Then the expression becomes a = b.
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.
The scenario is the following: I want to return the value of a when a is defined and else I want to return b. I need an expression because of JSX.
I am looking for a better way to write the expression a ? a : b where a and b are variables. I was trying !a&&b. The problem is when a is defined, then it returns of course false instead of the value of a which I want to receive then. I think I have my wires crossed at the moment. If someone has an idea, I would highly appreciated it.
You could take a default approach with a logical OR ||. This returns a, if this values is truthy, otherwise the default value of b.
a || b