https://stackoverflow.com/questions/2802055/what-does-the-construct-x-x-y-meanjavascript
||
)?The double pipe operator (||
) is the logical OR
operator . In most languages it works the following way:java
false
, it checks the second value. If it's true
, it returns true
and if it's false
, it returns false
.true
, it always returns true
, no matter what the second value is.So basically it works like this function:babel
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:app
| true false ------+--------------- true | true true false | true false
In other words, it's only false when both values are false.ide
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:this
(function(){}) || {}
If values are not boolean, JavaScript makes implicit conversation 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
.idea
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:spa
Surprised? Actually, it's "compatible" with the traditional ||
operator. It could be written as following function:code
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:ip
(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"
.
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.