Ruby's ||= (or equals) in JavaScript?
JavascriptRubySyntaxJavascript Problem Overview
I love Ruby's ||=
mechanism. If a variable doesn't exist or is nil
, then create it and set it equal to something:
amount # is nil
amount ||= 0 # is 0
amount ||= 5 # is 0
I need to do something similar in JavaScript now. What's the convention or proper way to do this? I know ||=
is not valid syntax. 2 obvious ways to handle it are:
window.myLib = window.myLib || {};
// or
if (!window.myLib)
window.myLib = {};
Javascript Solutions
Solution 1 - Javascript
Both are absolutely correct, but if you are looking for something that works like ||=
in ruby. The first method which is variable = variable || {}
is the one you are looking for :)
Solution 2 - Javascript
You can use the logical OR operator ||
which evaluates its right operand if lVal
is a falsy value.
Falsy values include e.g null, false, 0, "", undefined, NaN
x = x || 1
Solution 3 - Javascript
The operator you asked about has been proposed as a feature in JavaScript. It is currently at Stage 4, and it will be introduced in the next ECMAScript standard, which is expected to be published in 2021.
You can use it now using the plugin-proposal-logical-assignment-operators Babel plugin. I have never used that plugin, so I have no idea how well it works.
Solution 4 - Javascript
If you're working with objects, you can use destructuring (since ES6) like so:
({ myLib: window.myLib = {} } = window);
...but you don't gain anything over the accepted answer except confusion.
Solution 5 - Javascript
Solution 6 - Javascript
As of 2021, you can use ||=
with identical behavior to Ruby as long as you are transpiling or don't care about Opera/IE.
Logical OR assignement, ||=
is now supported natively in javascript on all major browsers except Opera and IE. Current caniuse matrix. MDN reference.
Typescript added support for the operator in version 4. If you need to support IE/Opera you can use the babel plugin to transpile for broad compatibility.
Solution 7 - Javascript
Ruby's ||= operator short circuits assignment. It can be thought of like this:
return a || a = b
So in javascript, this looks very similar:
return a || (a = b);
It seems as pointed out in the comments below however, that this literal ruby form is less efficient than the standard javascript idiom a = a || b.
For reference: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html
Solution 8 - Javascript
You can achieve the desired behaviour using |= operator in javascript for integers only. But you have to define the variable first.
let a = 0
a |= 100
console.log(a) // 100
For objects
let o = {}
o.a |= 100
console.log(o) // {a: 100}
For Arrays
let arr = []
arr[0] |= 100
console.log(arr) // [100]