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

Обидва абсолютно коректні, але якщо ви шукаєте щось, що працює як ||=у рубіні. Перший метод, який variable = variable || {}ви шукаєте :)


1
Будьте обережні, використовуючи це, якщо дійсне значення для xфальшивого, наприклад false, і ви хочете встановити типовий параметр лише тоді, коли він xне визначений.
Джошуа Пінтер

вище коментар правильний. Беручи ваш приклад, він не працюватиме так само в JS. let amount = 0;після цього amount = amount || 5 буде змінено суму до 5. Якщо ви не хочете, щоб це сталося, скористайтеся ??оператором замість ||.
Ешвін КумарС

@AshwinKumarS Або просто використовувати amount ??= 5;.
користувач4642212

@ user4642212 Я не думаю, що синтаксис працює в JS, чи не так?
AshwinKumarS

@AshwinKumarS Так, це так. Дивіться документацію , специфікацію , пропозицію .
користувач4642212

22

Ви можете використовувати логічний оператор АБО, ||який оцінює його правильний операнд, якщо lValє хибним значенням.

Фальшиві значення включають, наприклад null, false, 0, "", undefined, NaN

x = x || 1

Будьте обережні, використовуючи це, якщо дійсне значення для xфальшивого, наприклад false, і ви хочете встановити типовий параметр лише тоді, коли він xне визначений.
Джошуа Пінтер

4

Якщо ви працюєте з об'єктами, ви можете використовувати деструктуризацію (з ES6) так:

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

... але ви не отримуєте нічого над прийнятою відповіддю, крім плутанини.


1
"але ви не отримуєте нічого над прийнятою відповіддю, крім плутанини" - приємно. :)
lindes


1

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

Ви можете використовувати його зараз за допомогою плагіна Babel-plugin-offer-logic-призначення-операторів . Я ніколи не використовував цей плагін, тому не маю уявлення, наскільки добре він працює.


-1

Ruby's || = призначення короткого замикання оператора. Можна подумати так:

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

ах класний інструмент. як це виглядає, якщо х має значення і так коротке замикання?
chris

Я вважаю, що на jsperf слід чітко визначити, що цей тест повинен виявити ефективність короткого замикання. Я здогадуюсь, що V8 має спеціальну оптимізацію форми a = a || b.
jchook

3
FYI Схоже, що будь-яка різниця була оптимізована.
Чарльз Вуд

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.