People often write this in order to specify default values:
var thing = this || that;
which is, AFAIK, the same thing as this:
var thing = !!this ? this : that;
What do you call the technique used to specify defaults in the first code block?
NOTE: I am not asking what a logical OR is called. I am asking what the alternative to ternary notation (as written in the first code block) is called.
I'd call:
var a = A || B;
conditional assignment, since it is effectively:
if (!!A) {
a = A;
} else {
a = B;
}
and it is a replacement for the conditional operator : ?
var a = A? A : B;
It might also be called "logical assignment" since it involves a logical OR expression, but it doesn't seem to fit with what it's doing.
As mentioned elsewhere it is a logical OR.
The evaluation in question is a short-circuit evaluation.
It might help to look at it like this:
if ((foo = bar)) {
} else {
foo = baz;
}
The if statement evaluates to the value of bar. If bar is false, null etc the evaluation would be false.
Edit: Note:
It is perfectly valid to evaluate an assignment. If we say:
if ((a = b)) { ...
note that it is not:
if (a === b) { ...
the evaluation is done on the result of the assignment. Here it would evaluate to true if (b).
One should however always wrap them in parenthesis. This makes it clear that we are evaluating the assignment and not comparing the variables.
If one do not like it that is fair enough, (I'm rather used to it from C), but in this case it is merely for the sake of the answer to the question.
In the same way we have:
if ((foo = foo)) {
} else {
foo = baz;
}
var x = false;
console.log((x = x)); // False
As such we can say:
(x = x) || (x = y)
And to make it short:
x = (x || y);
or shorter:
x = x || y;
The double pipe is called the 'or' operator.
The double pipe is the Logical OR operator in JavaScript.
If the technique had a name I guess it would be "(ab)using the short-circuiting of the logical OR operator"
Related
I know about the ternary expression in javascript. However i don't know how to make this piece of code shorter.
if (x == false) {
x = true;
cancelAnimationFrame(BI.req);
}
else {
x = false;
BI.req = requestAnimationFrame(BI.fn.animate);
}
I guess I can make two separate functions and use them with the ternary expression. Something like this:
function cancel() {
x = true;
cancelAnimationFrame(BI.req);
}
function request() {
x = false;
BI.req = requestAnimationFrame(BI.fn.animate);
}
x == false ? cancel() : request();
But this doesn't feel like I am really making my code much shorter. Any suggestions will be much appreciated.
You can use ternary for the functions. And use ! operator to set x
x ? BI.req = requestAnimationFrame(BI.fn.animate) : cancelAnimationFrame(BI.req)
x = !x
Or even more shorter
(x = !x) ? cancelAnimationFrame(BI.req) : BI.req = requestAnimationFrame(BI.fn.animate)
The question was about shorter code so I answered this. Otherwise your own snippet is fine or consider Nina Answers because these two lines are completely non-readable.
You shouldn't use ternary operator like that too. Don't use ternary operator instead of if-else whenever there are two or move expressions in any block.
You could shorten it a bit by moving the assignment to the bottom and use a positive check.
if (x) {
BI.req = requestAnimationFrame(BI.fn.animate);
} else {
cancelAnimationFrame(BI.req);
}
x = !x;
I will not bore you with the story, but essentially I have some obscured JavaScript to deal with which all in all is fine, but I am struggling with 2 patterns in the code which I have never seen before.
This function below contains both patterns.
var a = function() {
if (h = true,
T(),
DEVELOPMENT && "#y0" == window.location.hash)
return game.playRegion = "eu",
game.playRoom = "ffa1",
game.playInvited = true,
game.myOriginalName = window.location.hash.substr(1),
void Games.start(game.myOriginalName, true);
f || (I(),
Games.updateRegion(false),
Games.updateType(false),
C())
}
First look at the if statement. I have never seen a if do assignment and call functions so I do not understand the logic of the conditional. Can I move the statements above the if or do the statements not run unless the full condition is met? Can I do this:
h = true;
T();
if (DEVELOPMENT && window.location.hash === "#y0"){}
What is going on with the return? The return is a series of statements so what is it actually returning? What is the void all about?
Nearly everything is an expression in JavaScript.
Assignments are also just expressions. a = b evaluates to b.
The Comma operator (which is used quite extensively) evaluates to the right side of the comma, so a, b, c evaluates to c.
void takes any expression, and always evaluates to undefined.
Therefore this:
return a = b, void c();
if(d(), e) {}
equals:
a = b;
c();
return undefined;
d();
if(e) {}
People often write this in order to specify default values:
var thing = this || that;
which is, AFAIK, the same thing as this:
var thing = !!this ? this : that;
What do you call the technique used to specify defaults in the first code block?
NOTE: I am not asking what a logical OR is called. I am asking what the alternative to ternary notation (as written in the first code block) is called.
I'd call:
var a = A || B;
conditional assignment, since it is effectively:
if (!!A) {
a = A;
} else {
a = B;
}
and it is a replacement for the conditional operator : ?
var a = A? A : B;
It might also be called "logical assignment" since it involves a logical OR expression, but it doesn't seem to fit with what it's doing.
As mentioned elsewhere it is a logical OR.
The evaluation in question is a short-circuit evaluation.
It might help to look at it like this:
if ((foo = bar)) {
} else {
foo = baz;
}
The if statement evaluates to the value of bar. If bar is false, null etc the evaluation would be false.
Edit: Note:
It is perfectly valid to evaluate an assignment. If we say:
if ((a = b)) { ...
note that it is not:
if (a === b) { ...
the evaluation is done on the result of the assignment. Here it would evaluate to true if (b).
One should however always wrap them in parenthesis. This makes it clear that we are evaluating the assignment and not comparing the variables.
If one do not like it that is fair enough, (I'm rather used to it from C), but in this case it is merely for the sake of the answer to the question.
In the same way we have:
if ((foo = foo)) {
} else {
foo = baz;
}
var x = false;
console.log((x = x)); // False
As such we can say:
(x = x) || (x = y)
And to make it short:
x = (x || y);
or shorter:
x = x || y;
The double pipe is called the 'or' operator.
The double pipe is the Logical OR operator in JavaScript.
If the technique had a name I guess it would be "(ab)using the short-circuiting of the logical OR operator"
In C I know true and false evaluate to 1 and 0 respectively. show in this case just prints to the screen... Not sure what's going on here. I'm expecting to get true back. This 1 is messing up my karma.
show(1 && true);
true
show(true && 1);
1
Simply put - that's how && is defined. In Javascript, a && b returns a if a is falsy and b if a is truthy.
Conversely a || b returns a if a is truthy and b if a is falsy.
This makes sense intuitively - if a is false in a && b, then why bother reading the rest of the expression? You already know the whole thing is false. So just return false. But Javascript makes the decision to return a, which is falsy, instead of making up the value false to return out of nowhere.
This is based on short-circuit evaluation common to all C-style languages.
It allows for much expressiveness in Javascript. For instance this pattern:
var foo = function(opts) {
opts = opts || {}
// ...
}
Implements an optional parameter opts. If opts is not passed in at all, opts = opts || {} will set opts to {}, so the rest of the code does not have to know opts wasn't passed.
In long-hand it is equivalent to the following:
var x = a || b; // is equivalent to
var x;
if(a) {
x = a;
}
else {
x = b;
}
and
var y = a && b; // is equivalent to
var y;
if(!a) {
y = a;
}
else {
y = b;
}
Therefore Javascript can be much more terse than C or Java, because simple if statements can be replaced by || or && entirely. Sometimes this makes the code more terse and less readable and more like Perl, other times it allows for new Javascript patterns, like opts = opts || {}.
Another use is in patterns like
var displayName = user.fullname || user.email;
Which means "use the full name if available; if not, fall back to email." I personally find this expressive and readable, but it's arguably terse and obscure depending on which part of the Javascript community you hail from. Because of examples like this, and essentially the fact that truthy values are far more diverse then falsy values, using short-circuit || is much more common than short-circuit &&, as in your question.
There are a few ways to do this in javascript.
Foremost and most readable and flexible is probably:
if (a){
//b
}
else {
//c
}
Something else that only* works with assigning and is less readable is:
var foo = 'c';
if (a){
foo = 'b';
}
My main question, though, is about the last two methods I can think of:
var foo = a ? b : c;
var foo = a && b || c;
Are there any differences between these two expressions? Other than the readability which both lack.
*although you could assign foo to be a function, then execute it after the if statement.
Suppose:
var a = false, b = '', c = 'bar';
Then:
var foo = a ? b : c; // foo == ''
var foo = a && b || c; // foo == 'bar'
The two are not equivalent; you should never use the boolean operators in place of the conditional operator. Like other answerers, I also am of the opinion that the conditional operator does not lack readability for simple expressions.
The ternary operator is certainly readable to me. Even moreso than the first example, since concise, logical code is always easier to understand than many lines of control code that do the same thing.
I don't agree the first lacks readability as long as it is used correctly, IOW a, b and c are simple expressions themselves. This operator does get abused though in circumstances it ought not.
Similarly the second expression, using the result foo as anything other than a boolean would not be good. Using the boolean operators to return non-boolean values because thats the way they work is just confusing. However as a boolean expression its reasonable.
var foo = a ? b : c; // foo is b when a is true else c.
var foo = a && b || c; // foo is true if a and b are true or c is true.
They do not evaluate to the same result as the latter is a boolean expression, not using a ternary operator.