Ruby's ||= (or equals) in JavaScript?

JavascriptRubySyntax

Javascript 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

Logical nullish assignment (??=)

x ??= 23

Documentation & Browser compatibility

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]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionat.View Question on Stackoverflow
Solution 1 - JavascriptDzung NguyenView Answer on Stackoverflow
Solution 2 - JavascriptMoritz RoesslerView Answer on Stackoverflow
Solution 3 - JavascriptElias ZamariaView Answer on Stackoverflow
Solution 4 - JavascriptInklingView Answer on Stackoverflow
Solution 5 - JavascriptIgor SukharevView Answer on Stackoverflow
Solution 6 - JavascriptMatt SandersView Answer on Stackoverflow
Solution 7 - JavascriptchrisView Answer on Stackoverflow
Solution 8 - JavascriptwallgeekView Answer on Stackoverflow