Related
Given this snippet of JavaScript...
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = a || b || c || d || e;
alert(f); // 4
Can someone please explain to me what this technique is called (my best guess is in the title of this question!)? And how/why it works exactly?
My understanding is that variable f will be assigned the nearest value (from left to right) of the first variable that has a value that isn't either null or undefined, but I've not managed to find much reference material about this technique and have seen it used a lot.
Also, is this technique specific to JavaScript? I know doing something similar in PHP would result in f having a true boolean value, rather than the value of d itself.
See short-circuit evaluation for the explanation. It's a common way of implementing these operators; it is not unique to JavaScript.
This is made to assign a default value, in this case the value of y, if the x variable is falsy.
The boolean operators in JavaScript can return an operand, and not always a boolean result as in other languages.
The Logical OR operator (||) returns the value of its second operand, if the first one is falsy, otherwise the value of the first operand is returned.
For example:
"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"
Falsy values are those who coerce to false when used in boolean context, and they are 0, null, undefined, an empty string, NaN and of course false.
Javacript uses short-circuit evaluation for logical operators || and &&. However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of a true, or false value.
The following values are considered falsy in JavaScript.
false
null
"" (empty string)
0
Nan
undefined
Ignoring the operator precedence rules, and keeping things simple, the following examples show which value halted the evaluation, and gets returned as a result.
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
The first 5 values upto NaN are falsy so they are all evaluated from left to right, until it meets the first truthy value - "Hello" which makes the entire expression true, so anything further up will not be evaluated, and "Hello" gets returned as a result of the expression. Similarly, in this case:
1 && [] && {} && true && "World" && null && 2010 // null
The first 5 values are all truthy and get evaluated until it meets the first falsy value (null) which makes the expression false, so 2010 isn't evaluated anymore, and null gets returned as a result of the expression.
The example you've given is making use of this property of JavaScript to perform an assignment. It can be used anywhere where you need to get the first truthy or falsy value among a set of values. This code below will assign the value "Hello" to b as it makes it easier to assign a default value, instead of doing if-else checks.
var a = false;
var b = a || "Hello";
You could call the below example an exploitation of this feature, and I believe it makes code harder to read.
var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);
Inside the alert, we check if messages is falsy, and if yes, then evaluate and return noNewMessagesText, otherwise evaluate and return newMessagesText. Since it's falsy in this example, we halt at noNewMessagesText and alert "Sorry, you have no new messages.".
Javascript variables are not typed, so f can be assigned an integer value even though it's been assigned through boolean operators.
f is assigned the nearest value that is not equivalent to false. So 0, false, null, undefined, are all passed over:
alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
There isn't any magic to it. Boolean expressions like a || b || c || d are lazily evaluated. Interpeter looks for the value of a, it's undefined so it's false so it moves on, then it sees b which is null, which still gives false result so it moves on, then it sees c - same story. Finally it sees d and says 'huh, it's not null, so I have my result' and it assigns it to the final variable.
This trick will work in all dynamic languages that do lazy short-circuit evaluation of boolean expressions. In static languages it won't compile (type error). In languages that are eager in evaluating boolean expressions, it'll return logical value (i.e. true in this case).
This question has already received several good answers.
In summary, this technique is taking advantage of a feature of how the language is compiled. That is, JavaScript "short-circuits" the evaluation of Boolean operators and will return the value associated with either the first non-false variable value or whatever the last variable contains. See Anurag's explanation of those values that will evaluate to false.
Using this technique is not good practice for several reasons; however.
Code Readability: This is using Boolean operators, and if the behavior of how this compiles is not understood, then the expected result would be a Boolean value.
Stability: This is using a feature of how the language is compiled that is inconsistent across multiple languages, and due to this it is something that could potentially be targeted for change in the future.
Documented Features: There is an existing alternative that meets this need and is consistent across more languages. This would be the ternary operator:
() ? value 1: Value 2.
Using the ternary operator does require a little more typing, but it clearly distinguishes between the Boolean expression being evaluated and the value being assigned. In addition it can be chained, so the types of default assignments being performed above could be recreated.
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = ( a ) ? a :
( b ) ? b :
( c ) ? c :
( d ) ? d :
e;
alert(f); // 4
Return output first true value.
If all are false return last false value.
Example:-
null || undefined || false || 0 || 'apple' // Return apple
It's setting the new variable (z) to either the value of x if it's "truthy" (non-zero, a valid object/array/function/whatever it is) or y otherwise. It's a relatively common way of providing a default value in case x doesn't exist.
For example, if you have a function that takes an optional callback parameter, you could provide a default callback that doesn't do anything:
function doSomething(data, callback) {
callback = callback || function() {};
// do stuff with data
callback(); // callback will always exist
}
Its called Short circuit operator.
Short-circuit evaluation says, the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression. when the first argument of the OR (||) function evaluates to true, the overall value must be true.
It could also be used to set a default value for function argument.`
function theSameOldFoo(name){
name = name || 'Bar' ;
console.log("My best friend's name is " + name);
}
theSameOldFoo(); // My best friend's name is Bar
theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar`
It means that if x is set, the value for z will be x, otherwise if y is set then its value will be set as the z's value.
it's the same as
if(x)
z = x;
else
z = y;
It's possible because logical operators in JavaScript doesn't return boolean values but the value of the last element needed to complete the operation (in an OR sentence it would be the first non-false value, in an AND sentence it would be the last one). If the operation fails, then false is returned.
It will evaluate X and, if X is not null, the empty string, or 0 (logical false), then it will assign it to z. If X is null, the empty string, or 0 (logical false), then it will assign y to z.
var x = '';
var y = 'bob';
var z = x || y;
alert(z);
Will output 'bob';
According to the Bill Higgins' Blog post; the Javascript logical OR assignment idiom (Feb. 2007), this behavior is true as of v1.2 (at least)
He also suggests another use for it (quoted):
"lightweight normalization of cross-browser differences"
// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;
If I have a ternary that is testing for a greater than/less than condition and that value is then assigned back to the original variable, is there short hand for that?
var firstVar = 1
var secondVar = 2
firstVar = firstVar > secondVar ? firstVar : secondVar
Is there a simpler way to write line 3?
I can think of another possible one-liner shortcut for your test, using || operator (logical OR).
var firstVar = 1;
var secondVar = 2;
firstVar > secondVar || (firstVar = secondVar);
console.log(firstVar);
Basically, expression on third line returns true, if first operand is evaluated as true (whole expression will return "truthy" return value of expression in first operand in general). Otherwise, it will return expression in second operand (return value of variable assignment in this case). However, return value of this whole expression isn't assigned to any variable, because goal was only to perform specific assignment (second operand), if given condition (first operand) wasn't satisfied.
Also, this method might not be as intuitive as simple if statement, because variable assignment can only happen, if condition in first operand is not satisfied. It will work like variable assignment in else statement after empty if statement from previous answer. Or you can inverse statement in first operand, if this pattern is not matching your original logic.
Note: Variable assignment in second operand has to be in parentheses, because it has lower precedence than logical OR. You might want to check this table on MDN, if you are not sure about precedence of operators while constructing expressions.
I will go with a simple if statement which only assigns the value if the condition is true.
var firstVar = 1;
var secondVar = 2;
if (firstVar <= secondVar) firstVar = secondVar;
console.log(firstVar);
Given this snippet of JavaScript...
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = a || b || c || d || e;
alert(f); // 4
Can someone please explain to me what this technique is called (my best guess is in the title of this question!)? And how/why it works exactly?
My understanding is that variable f will be assigned the nearest value (from left to right) of the first variable that has a value that isn't either null or undefined, but I've not managed to find much reference material about this technique and have seen it used a lot.
Also, is this technique specific to JavaScript? I know doing something similar in PHP would result in f having a true boolean value, rather than the value of d itself.
See short-circuit evaluation for the explanation. It's a common way of implementing these operators; it is not unique to JavaScript.
This is made to assign a default value, in this case the value of y, if the x variable is falsy.
The boolean operators in JavaScript can return an operand, and not always a boolean result as in other languages.
The Logical OR operator (||) returns the value of its second operand, if the first one is falsy, otherwise the value of the first operand is returned.
For example:
"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"
Falsy values are those who coerce to false when used in boolean context, and they are 0, null, undefined, an empty string, NaN and of course false.
Javacript uses short-circuit evaluation for logical operators || and &&. However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of a true, or false value.
The following values are considered falsy in JavaScript.
false
null
"" (empty string)
0
Nan
undefined
Ignoring the operator precedence rules, and keeping things simple, the following examples show which value halted the evaluation, and gets returned as a result.
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
The first 5 values upto NaN are falsy so they are all evaluated from left to right, until it meets the first truthy value - "Hello" which makes the entire expression true, so anything further up will not be evaluated, and "Hello" gets returned as a result of the expression. Similarly, in this case:
1 && [] && {} && true && "World" && null && 2010 // null
The first 5 values are all truthy and get evaluated until it meets the first falsy value (null) which makes the expression false, so 2010 isn't evaluated anymore, and null gets returned as a result of the expression.
The example you've given is making use of this property of JavaScript to perform an assignment. It can be used anywhere where you need to get the first truthy or falsy value among a set of values. This code below will assign the value "Hello" to b as it makes it easier to assign a default value, instead of doing if-else checks.
var a = false;
var b = a || "Hello";
You could call the below example an exploitation of this feature, and I believe it makes code harder to read.
var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);
Inside the alert, we check if messages is falsy, and if yes, then evaluate and return noNewMessagesText, otherwise evaluate and return newMessagesText. Since it's falsy in this example, we halt at noNewMessagesText and alert "Sorry, you have no new messages.".
Javascript variables are not typed, so f can be assigned an integer value even though it's been assigned through boolean operators.
f is assigned the nearest value that is not equivalent to false. So 0, false, null, undefined, are all passed over:
alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
There isn't any magic to it. Boolean expressions like a || b || c || d are lazily evaluated. Interpeter looks for the value of a, it's undefined so it's false so it moves on, then it sees b which is null, which still gives false result so it moves on, then it sees c - same story. Finally it sees d and says 'huh, it's not null, so I have my result' and it assigns it to the final variable.
This trick will work in all dynamic languages that do lazy short-circuit evaluation of boolean expressions. In static languages it won't compile (type error). In languages that are eager in evaluating boolean expressions, it'll return logical value (i.e. true in this case).
This question has already received several good answers.
In summary, this technique is taking advantage of a feature of how the language is compiled. That is, JavaScript "short-circuits" the evaluation of Boolean operators and will return the value associated with either the first non-false variable value or whatever the last variable contains. See Anurag's explanation of those values that will evaluate to false.
Using this technique is not good practice for several reasons; however.
Code Readability: This is using Boolean operators, and if the behavior of how this compiles is not understood, then the expected result would be a Boolean value.
Stability: This is using a feature of how the language is compiled that is inconsistent across multiple languages, and due to this it is something that could potentially be targeted for change in the future.
Documented Features: There is an existing alternative that meets this need and is consistent across more languages. This would be the ternary operator:
() ? value 1: Value 2.
Using the ternary operator does require a little more typing, but it clearly distinguishes between the Boolean expression being evaluated and the value being assigned. In addition it can be chained, so the types of default assignments being performed above could be recreated.
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = ( a ) ? a :
( b ) ? b :
( c ) ? c :
( d ) ? d :
e;
alert(f); // 4
Return output first true value.
If all are false return last false value.
Example:-
null || undefined || false || 0 || 'apple' // Return apple
It's setting the new variable (z) to either the value of x if it's "truthy" (non-zero, a valid object/array/function/whatever it is) or y otherwise. It's a relatively common way of providing a default value in case x doesn't exist.
For example, if you have a function that takes an optional callback parameter, you could provide a default callback that doesn't do anything:
function doSomething(data, callback) {
callback = callback || function() {};
// do stuff with data
callback(); // callback will always exist
}
Its called Short circuit operator.
Short-circuit evaluation says, the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression. when the first argument of the OR (||) function evaluates to true, the overall value must be true.
It could also be used to set a default value for function argument.`
function theSameOldFoo(name){
name = name || 'Bar' ;
console.log("My best friend's name is " + name);
}
theSameOldFoo(); // My best friend's name is Bar
theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar`
It means that if x is set, the value for z will be x, otherwise if y is set then its value will be set as the z's value.
it's the same as
if(x)
z = x;
else
z = y;
It's possible because logical operators in JavaScript doesn't return boolean values but the value of the last element needed to complete the operation (in an OR sentence it would be the first non-false value, in an AND sentence it would be the last one). If the operation fails, then false is returned.
It will evaluate X and, if X is not null, the empty string, or 0 (logical false), then it will assign it to z. If X is null, the empty string, or 0 (logical false), then it will assign y to z.
var x = '';
var y = 'bob';
var z = x || y;
alert(z);
Will output 'bob';
According to the Bill Higgins' Blog post; the Javascript logical OR assignment idiom (Feb. 2007), this behavior is true as of v1.2 (at least)
He also suggests another use for it (quoted):
"lightweight normalization of cross-browser differences"
// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;
Sorry if this question is not upto the level of the site i cannot find help anywhere else. I have just started to learn JavaScript but i am stuck at an example code given in my text-book
var a = null;
function b() {return "B";}
(a || b)();
! "B"
There is not enough explanation given for the code and i am not able to figure out how does it work, can anyone help me please
Thanks
Akash
I assume the source of your confusion comes from the third and fourth line.
Let's start with the third line: (a || b)();.
First a is evaluated and if it is not null or undefined then the result of this expression is a(), otherwise the result is b().
In your code snippet, a is null, so the expression is evaluated to b() which simply returns "B".
The OR || operator looks at its operands one by one, until it finds a value that is truthy and it returns it, if all the values are falsy then the last operand is returned.
For more information about truthy and falsy values, check here
Now this line ! "B", all strings in JavaScript are evaluated to true except for the empty string "", so the result of the previous expression is ! true so it is false.
The key is in how the || operator works. This line:
(a || b)();
is equivalent to this:
var f;
if (a)
f = a;
else
f = b;
f();
The || operator works by first evaluating the left side (in this case, a). It then checks to see whether that value is "truthy", which means that it's not null, 0, the empty string, and a couple other things. In this case it's clearly null, so it's not "truthy".
Thus the || operator goes on to evaluate the right side (in this case, b), and that value is taken as the result of the || operation. What's "b"? It's that little function that returns the string "B" when called.
Thus after the || operation is done, you're left with a reference to that function, and the subsequent () function call operator causes that function to be called.
There are two variables, a which is null and b which is a function that always returns the string "B". (a || b)() demonstrates a bit how logical && and || work in JavaScript - the evaluation is short-circuited and the last value evaluated is the value of the entire expression. Since a is null which is falsy, (a || b)() evaluates to b(), so you get the "B" print.
In general:
(a || b); //a if a is truthy, otherwise b
(a && b); //a if a is falsy, otherwise b
Falsy values are null, undefined, 0, the empty string "", NaN and of course false. Everything else is truthy.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does “options = options || {}” mean in Javascript?
What is the meaning of the || in the second argument?
var obj = this;
var settings = $.extend({
param: 'defaultValue'
}, options || {});
Also would be nice if anyone knows how to search that character("|") here or in google! Thank you
That would be the logical OR. The statement will return the first truth-y value it finds.
In this case, if options is null (or any other value that isn't truth-y) it will evaluate to false. The || will then return the empty object.
That is some kind of fallback value or default value. So if the object is null or false the second value is used.
More importantly in that scenario, if options is not defined then an empty object {} is passed as an argument. Its kind of a side-effect use case of the logical OR operator. More specifically, it uses short circuiting. For example in the below case
a || b
if a is true then b never gets executed, but if a is false then b gets executed. Hence in the example you have shown, if options is not defined and thus false, then {} gets executed and thus passed as a parameter.
|| = or
As in the comparison operator.
|| = "OR". Example:
alert(false || false || false || "I'm valid!"); // alerts "I'm valid"
In your question, the example above demonstrates that the function requires an object for it's options. In this case, if the local variable "options" is not available, then just pass an empty object. Later, in the function that's being called, it's probably setting default values in that new object.