What does the construct x = x || y mean?
Asked Answered
H

12

310

I am debugging some JavaScript and can't explain what this || does:

function (title, msg) {
  var title = title || 'Error';
  var msg   = msg || 'Error on Request';
}

Why is this guy using var title = title || 'ERROR'? I sometimes see it without a var declaration as well.

Howardhowarth answered 10/5, 2010 at 10:58 Comment(14)
People have already answered this... but be extremely aware of the fact that the second value is chosen if the first value is falsy, not JUST undefined. The amount of times I've seen doWeDoIt = doWeDoIt || true, is enough to make me cry. (i.e doWeDoIt will now never be false)Spirant
see also What does “options = options || {}” mean in Javascript?Sargassum
For those with experience with C#, the double-pipe operator is equivalent to null-coalesce operator ??. Javascript evaluates non-null objects like true (or better evalualtes null objects to false)Soelch
It just a simple way to assign a default value in one line. like when you assign a conditional value like this: int y = x > 2 ? x : 1 or Object o = person ?: new Person().Alliance
Don't feel bad - JS is the only goofy language allowing this horrible coding....that and teaching that it's proper to nest every function into lines of code and throwing them away making them disposable and unusable a 2nd time. :) I'm 30 yrs into coding and held off touching JS until not long ago myself and I feel your pain all I can say is, keep a "makes no sense, it's only in JS" cheetsheet handy it's the only way I've gotten by! :)Whithersoever
TL;DR answer is found in a similar question: https://mcmap.net/q/24502/-is-there-a-better-way-to-do-optional-function-parameters-in-javascript-duplicate (typeof var === 'undefined' ? default : var)Portfire
Please consider changing the accepted answer to my answer.Deason
@Spirant maybe it's not someones intention to ever make doWeDoIt false. So stop loading tearsJS. :DMotion
With respect to the naming, selector operator sounds good so far.Faus
@usr-local-ΕΨΗΕΛΩΝ re "the double-pipe operator is equivalent to null-coalesce operator ??" NO - don't use it like that. Its the error-prone JS falsy version of null-coelesce. Fortunately, there is now a proper ?? in JS - before that was added, the correct equivalent to null-coelesce was value != null ? value : YOUR_DEFAULT.Cramer
@Cramer I wrote that back in 2015...............................Soelch
@usr-local-ΕΨΗΕΛΩΝ - I saw that date, and I covered that time frame: before that was added, the correct equivalent to null-coelesce was value != null ? value : YOUR_DEFAULT. Using || as if it was null coalesce was never a good habit. Subtle bug if you encountered any "falsey" value, but were thinking of it as "not null" rather than "not falsey". Maybe call || the "truthy coalesce operator"? :)Cramer
@Spirant what you wrote almost confused because I spent so much time trying to understand the doWeDoit = doWeDoit || true. I thought I didn't really understand it. But infact it's simply because what you've written is nonsense code. I'm surprised you've seen someone write that code EVER. if someone wrote that I don't understand what the thinking would be. why wouldn't they just set something to being true if they wanted it to be true.Heatherheatherly
@MrBrN197 They didn't want it to be true; that's the point. They wanted it to become true if it was not provided and hence undefined. They used the construct from the perspective of providing defaults, forgetting about its main use as a logic operator.Nikolia
F
244

It means the title argument is optional. So if you call the method with no arguments it will use a default value of "Error".

It's shorthand for writing:

if (!title) {
  title = "Error";
}

This kind of shorthand trick with boolean expressions is common in Perl too. With the expression:

a OR b

it evaluates to true if either a or b is true. So if a is true you don't need to check b at all. This is called short-circuit boolean evaluation so:

var title = title || "Error";

basically checks if title evaluates to false. If it does, it "returns" "Error", otherwise it returns title.

Follicle answered 10/5, 2010 at 11:0 Comment(2)
Sorry to be picky, but the argument isn't optional, the argument is checkedPosology
This is NOT the answer and I agree with the last comment it's not even optional. No part of this answer is correct even the Perl reference since the Perl statement actually makes SENSE and is evaluated in a completely different way. The JS is eval in a much more "converted" boolean logic method that I too find much more confusing to read/write. The answer below titled "What is the double pipe operator" is actually a correct answer.Whithersoever
A
262

What is the double pipe operator (||)?

The double pipe operator (||) is the logical OR operator . In most languages it works the following way:

  • If the first value is false, it checks the second value. If that's true, it returns true and if the second value is false, it returns false.
  • If the first value is true, it always returns true, no matter what the second value is.

So basically it works like this function:

function or(x, y) {
  if (x) {
    return true;
  } else if (y) {
    return true;
  } else {
    return false;
  }
}

If you still don't understand, look at this table:

      | true   false  
------+---------------
true  | true   true   
false | true   false  

In other words, it's only false when both values are false.

How is it different in JavaScript?

JavaScript is a bit different, because it's a loosely typed language. In this case it means that you can use || operator with values that are not booleans. Though it makes no sense, you can use this operator with for example a function and an object:

(function(){}) || {}

What happens there?

If values are not boolean, JavaScript makes implicit conversion to boolean. It means that if the value is falsey (e.g. 0, "", null, undefined (see also All falsey values in JavaScript)), it will be treated as false; otherwise it's treated as true.

So the above example should give true, because empty function is truthy. Well, it doesn't. It returns the empty function. That's because JavaScript's || operator doesn't work as I wrote at the beginning. It works the following way:

  • If the first value is falsey, it returns the second value.
  • If the first value is truthy, it returns the first value.

Surprised? Actually, it's "compatible" with the traditional || operator. It could be written as following function:

function or(x, y) {
  if (x) {
    return x;
  } else {
    return y;
  }
}

If you pass a truthy value as x, it returns x, that is, a truthy value. So if you use it later in if clause:

(function(x, y) {
  var eitherXorY = x || y;
  if (eitherXorY) {
    console.log("Either x or y is truthy.");
  } else {
    console.log("Neither x nor y is truthy");
  }
}(true/*, undefined*/));

you get "Either x or y is truthy.".

If x was falsey, eitherXorY would be y. In this case you would get the "Either x or y is truthy." if y was truthy; otherwise you'd get "Neither x nor y is truthy".

The actual question

Now, when you know how || operator works, you can probably make out by yourself what does x = x || y mean. If x is truthy, x is assigned to x, so actually nothing happens; otherwise y is assigned to x. It is commonly used to define default parameters in functions. However, it is often considered a bad programming practice, because it prevents you from passing a falsey value (which is not necessarily undefined or null) as a parameter. Consider following example:

function badFunction(/* boolean */flagA) {
  flagA = flagA || true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

It looks valid at the first sight. However, what would happen if you passed false as flagA parameter (since it's boolean, i.e. can be true or false)? It would become true. In this example, there is no way to set flagA to false.

It would be a better idea to explicitly check whether flagA is undefined, like that:

function goodFunction(/* boolean */flagA) {
  flagA = typeof flagA !== "undefined" ? flagA : true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

Though it's longer, it always works and it's easier to understand.


You can also use the ES6 syntax for default function parameters, but note that it doesn't work in older browsers (like IE). If you want to support these browsers, you should transpile your code with Babel.

See also Logical Operators on MDN.

Afoot answered 10/1, 2016 at 16:18 Comment(5)
+1 - by far the most correct and complete answer. And, for those with this question (some of us veteran coders new to JS included) should certainly focus the most out of this entire answer on this line: "Though it makes no sense" because this "loosley typed" will simply never make sense to those of us that grew up without it. For us, a boolean operator is just that and ONLY that......and whomever ever thought it would be a good idea to have to stop and think through some wacky conversion of non-boolean values to boolean while reading/writing code, forgot to take their meds that day! :)Whithersoever
+1, in a nutshell: title = title || 'Error' means if (title) { title = title; } else { title = 'Error'; }Motion
I actually don't agree with the "though it makes no sense" line. I understand the line would not compile in C, for example, but it is well-understood if you came from Ruby for example, or even Groovy. In Ruby you could express it even shorter, as title ||= 'Error'.Troup
FWIW, I would have written the code snippet as function or(x, y) { if (x) return x; else return y; }. This is essentially what is done in all languages AFAIK, both strict and loosely typed, including JavaScript. [ignoring short-circuiting for this discussion] The only difference between different languages is under what conditions if (x) is true. [In a strictly typed language, if (x) is only true for true, so return x is identical to return true.]Cramer
Revisited in 2021: use the nullish coalescing operator (??)Nikolia
F
244

It means the title argument is optional. So if you call the method with no arguments it will use a default value of "Error".

It's shorthand for writing:

if (!title) {
  title = "Error";
}

This kind of shorthand trick with boolean expressions is common in Perl too. With the expression:

a OR b

it evaluates to true if either a or b is true. So if a is true you don't need to check b at all. This is called short-circuit boolean evaluation so:

var title = title || "Error";

basically checks if title evaluates to false. If it does, it "returns" "Error", otherwise it returns title.

Follicle answered 10/5, 2010 at 11:0 Comment(2)
Sorry to be picky, but the argument isn't optional, the argument is checkedPosology
This is NOT the answer and I agree with the last comment it's not even optional. No part of this answer is correct even the Perl reference since the Perl statement actually makes SENSE and is evaluated in a completely different way. The JS is eval in a much more "converted" boolean logic method that I too find much more confusing to read/write. The answer below titled "What is the double pipe operator" is actually a correct answer.Whithersoever
S
30

If title is not set, use 'ERROR' as default value.

More generic:

var foobar = foo || default;

Reads: Set foobar to foo or default. You could even chain this up many times:

var foobar = foo || bar || something || 42;
Showcase answered 10/5, 2010 at 10:59 Comment(1)
I found it confusing because the variables have the same name. Much easier when they don't.Armed
W
14

Explaining this a little more...

The || operator is the logical-or operator. The result is true if the first part is true and it is true if the second part is true and it is true if both parts are true. For clarity, here it is in a table:

 X | Y | X || Y 
---+---+--------
 F | F |   F    
---+---+--------
 F | T |   T    
---+---+--------
 T | F |   T    
---+---+--------
 T | T |   T    
---+---+--------

Now notice something here? If X is true, the result is always true. So if we know that X is true we don't have to check Y at all. Many languages thus implement "short circuit" evaluators for logical-or (and logical-and coming from the other direction). They check the first element and if that's true they don't bother checking the second at all. The result (in logical terms) is the same, but in terms of execution there's potentially a huge difference if the second element is expensive to calculate.

So what does this have to do with your example?

var title   = title || 'Error';

Let's look at that. The title element is passed in to your function. In JavaScript if you don't pass in a parameter, it defaults to a null value. Also in JavaScript if your variable is a null value it is considered to be false by the logical operators. So if this function is called with a title given, it is a non-false value and thus assigned to the local variable. If, however, it is not given a value, it is a null value and thus false. The logical-or operator then evaluates the second expression and returns 'Error' instead. So now the local variable is given the value 'Error'.

This works because of the implementation of logical expressions in JavaScript. It doesn't return a proper boolean value (true or false) but instead returns the value it was given under some rules as to what's considered equivalent to true and what's considered equivalent to false. Look up your JavaScript reference to learn what JavaScript considers to be true or false in boolean contexts.

Widen answered 10/5, 2010 at 11:14 Comment(0)
C
12

|| is the boolean OR operator. As in JavaScript, undefined, null, 0, false are considered as falsy values.

It simply means

true || true = true
false || true = true
true || false = true
false || false = false

undefined || "value" = "value"
"value" || undefined = "value"
null || "value" = "value"
"value" || null = "value"
0 || "value" = "value"
"value" || 0 = "value"
false || "value" = "value"
"value" || false = "value"
Calamondin answered 19/12, 2019 at 8:55 Comment(0)
R
11

Basically, it checks if the value before the || evaluates to true. If yes, it takes this value, and if not, it takes the value after the ||.

Values for which it will take the value after the || (as far as I remember):

  • undefined
  • false
  • 0
  • '' (Null or Null string)
Rearm answered 10/5, 2010 at 11:2 Comment(1)
false || null || undefined || 0 || '' || 'you forgot null'Teasley
P
8

Whilst Cletus' answer is correct, I feel more detail should be added in regards to "evaluates to false" in JavaScript.

var title = title || 'Error';
var msg   = msg || 'Error on Request';

Is not just checking if title/msg has been provided, but also if either of them are falsy. i.e. one of the following:

  • false.
  • 0 (zero)
  • "" (empty string)
  • null.
  • undefined.
  • NaN (a special Number value meaning Not-a-Number!)

So in the line

var title = title || 'Error';

If title is truthy (i.e., not falsy, so title = "titleMessage" etc.) then the Boolean OR (||) operator has found one 'true' value, which means it evaluates to true, so it short-circuits and returns the true value (title).

If title is falsy (i.e. one of the list above), then the Boolean OR (||) operator has found a 'false' value, and now needs to evaluate the other part of the operator, 'Error', which evaluates to true, and is hence returned.

It would also seem (after some quick firebug console experimentation) if both sides of the operator evaluate to false, it returns the second 'falsy' operator.

i.e.

return ("" || undefined)

returns undefined, this is probably to allow you to use the behavior asked about in this question when trying to default title/message to "". i.e. after running

var foo = undefined
foo = foo || ""

foo would be set to ""

Polar answered 14/1, 2016 at 10:11 Comment(0)
F
7

Double pipe stands for logical "OR". This is not really the case when the "parameter not set", since strictly in JavaScript if you have code like this:

function foo(par) {
}

Then calls

foo()
foo("")
foo(null)
foo(undefined)
foo(0)

are not equivalent.

Double pipe (||) will cast the first argument to Boolean and if the resulting Boolean is true - do the assignment, otherwise it will assign the right part.

This matters if you check for unset parameter.

Let's say, we have a function setSalary that has one optional parameter. If the user does not supply the parameter then the default value of 10 should be used.

If you do the check like this:

function setSalary(dollars) {
    salary = dollars || 10
}

This will give an unexpected result for a call like:

setSalary(0)

It will still set the 10 following the flow described above.

Fiacre answered 10/5, 2010 at 11:11 Comment(0)
D
6

Double pipe operator

This example may be useful:

var section = document.getElementById('special');
if(!section){
     section = document.getElementById('main');
}

It can also be:

var section = document.getElementById('special') || document.getElementById('main');
Dianoia answered 10/5, 2010 at 11:1 Comment(0)
D
4

To add some explanation to all said before me, I should give you some examples to understand logical concepts.

var name = false || "Mohsen"; # name equals to Mohsen
var family = true || "Alizadeh" # family equals to true

It means if the left side evaluated as a true statement it will be finished and the left side will be returned and assigned to the variable. in other cases the right side will be returned and assigned.

And operator have the opposite structure like below.

var name = false && "Mohsen" # name equals to false
var family = true && "Alizadeh" # family equals to Alizadeh
Duda answered 14/1, 2016 at 21:34 Comment(0)
S
2

Quote: "What does the construct x = x || y mean?"

Assigning a default value.

This means providing a default value of y to x, in case x is still waiting for its value but hasn't received it yet or was deliberately omitted in order to fall back to a default.

Scarbrough answered 9/5, 2016 at 13:34 Comment(1)
That's the exact meaning of the construct and the only meaning of it. And it was vastly as a subroutine in writing functions that could be fetched as prototypes, standalone functions, and also as borrowed methods to be applied on another element. Where its main and only duty was to modify the reference of the target. Example: function getKeys(x) { x = x || this ; .... } which could be used without modification as a standalone function, as a property method in prototypes and as a method of an element which can get another element as its argument as ` [element].getKeys(anotherElement);`Scarbrough
S
-5

And I have to add one more thing: This bit of shorthand is an abomination. It misuses an accidental interpreter optimization (not bothering with the second operation if the first is truthy) to control an assignment. That use has nothing to do with the purpose of the operator. I do not believe it should ever be used.

I prefer the ternary operator for initialization, for example,

var title = title?title:'Error';

This uses a one-line conditional operation for its correct purpose. It still plays unsightly games with truthiness but, that's JavaScript for you.

Shizukoshizuoka answered 29/4, 2016 at 19:43 Comment(1)
Short-circuit Boolean operators were criticised  by Edsger W. Dijkstra and others, but they go a long time back and are in a lot of languages, including C, Pascal (Turbo Pascal only?), Perl, C#, Go, Kotlin, Python, etc. For instance, Python only has short-circuit Boolean operators.Kwakiutl

© 2022 - 2024 — McMap. All rights reserved.