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]

Вопрос не в |или |=. Желаемое поведение в вопросе не связано с поразрядными операциями.
user4642212

Вы правы, я отредактирую ответ соответственно
wallgeek

Ред. Надеюсь, теперь это имеет смысл.
wallgeek
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.