Ruby's || = (или равно) в JavaScript?

128

Мне нравится ||=механизм Руби . Если переменная не существует или есть nil, создайте ее и установите равной чему-нибудь:

amount # is nil
amount ||= 0 # is 0
amount ||= 5 # is 0

Сейчас мне нужно сделать что-то подобное в JavaScript. Каковы правила или правильный способ сделать это? Я знаю, что ||=это неверный синтаксис. 2 очевидных способа справиться с этим:

window.myLib = window.myLib || {};

// or

if (!window.myLib)
  window.myLib = {};
в.
источник

Ответы:

152

Оба абсолютно правильны, но если вы ищете что-то, что работает как ||=в ruby. Первый метод, который variable = variable || {}вы ищете :)

Джунг Нгуен
источник
1
Осторожно используйте это, если допустимое значение для xявляется ложным, например false, и вы хотите установить значение по умолчанию, только если xоно не определено.
Джошуа Пинтер,
выше комментарий правильный. В вашем примере это не будет работать так же в JS. let amount = 0;с последующим amount = amount || 5 изменением суммы на 5. Если вы не хотите, чтобы это произошло, используйте ??оператор вместо ||.
AshwinKumarS
@AshwinKumarS Или просто используйте amount ??= 5;.
user4642212
@ user4642212 Я не думаю, что синтаксис работает в JS, не так ли?
AshwinKumarS
@AshwinKumarS Да, это так. Смотрите документацию , спецификацию , предложение .
user4642212
22

Вы можете использовать логический оператор ИЛИ, ||который оценивает свой правый операнд, если lValзначение ложное.

Ложные значения включают, например, null, false, 0, "", undefined, NaN

x = x || 1
Мориц Ресслер
источник
Осторожно используйте это, если допустимое значение для xявляется ложным, например false, и вы хотите установить значение по умолчанию, только если xоно не определено.
Джошуа Пинтер,
4

Если вы работаете с объектами, вы можете использовать деструктуризацию (начиная с ES6) следующим образом:

({ myLib: window.myLib = {} } = window);

... но вы ничего не получите от принятого ответа, кроме путаницы.

догадка
источник
1
"но вы ничего не получите от принятого ответа, кроме путаницы" - приятно. :)
lindes
Бьюсь об заклад, кто-то воспримет это как причину ненависти к javascript
Вольпер
1

Оператор, о котором вы спрашивали , был предложен как функция в JavaScript . В настоящее время он находится на этапе 3 , поэтому он еще не является официальной частью языка, но он будет принят с минимальными изменениями в случае обнаружения серьезных неожиданных проблем.

Теперь вы можете использовать его, используя плагин Babel-предложения-логического-присваивания-надстройки . Я никогда не использовал этот плагин, поэтому понятия не имею, насколько хорошо он работает.

Элиас Замария
источник
-1

Оператор Ruby || = сокращает присвоение. Это можно представить так:

return a || a = b

Итак, в javascript это выглядит очень похоже:

return a || (a = b);

Однако, как указано в комментариях ниже, эта буквальная форма рубина менее эффективна, чем стандартная идиома javascript a = a || б.

Для справки: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html

Крис
источник
1
На практике кажется, что a = a || bформа более оптимальна. Jsperf.com/x-or-x-equals-0-vs-x-equals-x-or-0/3
jchook 06
ну классный инструмент. как это выглядит, если x имеет значение и поэтому замыкается?
Крис
Я считаю, что разборка jsperf должна быть явной, поэтому этот тест должен показать производительность при коротком замыкании. Я предполагаю, что V8 имеет специальную оптимизацию для формы a = a || b.
jchook 09
3
К вашему сведению. Похоже, что разница, которая была, теперь была оптимизирована.
Чарльз Вуд
a || (a = b)имеет правильную семантику для вывода имен функций. В настоящее время обсуждается новое предложение.
user4642212
-1

Вы можете добиться желаемого поведения, используя оператор | = в javascript только для целых чисел. Но сначала вы должны определить переменную.

let a = 0
a |= 100
console.log(a) // 100

Для объектов

let o = {}
o.a |= 100
console.log(o) // {a: 100}

Для массивов

let arr = []
arr[0] |= 100
console.log(arr) // [100]
wallgeek
источник
Вопрос не в |или |=. Желаемое поведение в вопросе не связано с поразрядными операциями.
user4642212
Вы правы, я отредактирую ответ соответственно
wallgeek
Ред. Надеюсь, теперь это имеет смысл.
wallgeek