Ruby's || = (lub równa się) w JavaScript?


128

Uwielbiam ||=mechanizm Ruby . Jeśli zmienna nie istnieje lub istnieje nil, utwórz ją i ustaw jako coś:

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

Muszę teraz zrobić coś podobnego w JavaScript. Jaka jest konwencja lub właściwy sposób, aby to zrobić? Wiem, że ||=to nieprawidłowa składnia. 2 oczywiste sposoby radzenia sobie z tym to:

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

// or

if (!window.myLib)
  window.myLib = {};

Odpowiedzi:


152

Obie są absolutnie poprawne, ale jeśli szukasz czegoś, co działa jak ||=w rubinie. Pierwsza metoda, której variable = variable || {}szukasz :)


1
Ostrożnie używaj tego, jeśli prawidłowa wartość dla xjest fałszywa, na przykład false, i chcesz ustawić wartość domyślną tylko wtedy, gdy xjest niezdefiniowana.
Joshua Pinter

powyższy komentarz jest słuszny. Biorąc pod uwagę Twój przykład, w JS to nie będzie działać w ten sam sposób. let amount = 0;a następnie amount = amount || 5 zmieni liczbę na 5. Jeśli nie chcesz, aby tak się stało, użyj ??operatora zamiast ||.
AshwinKumarS

@AshwinKumarS Lub po prostu użyj amount ??= 5;.
user4642212

@ user4642212 Nie sądzę, że składnia działa w JS, prawda?
AshwinKumarS

@AshwinKumarS Tak, to prawda. Zobacz dokumentację , specyfikację , ofertę .
user4642212

22

Możesz użyć logicznego operatora OR, ||który ocenia jego prawy operand, jeśli lValjest fałszywą wartością.

Do fałszywych wartości należą np null, false, 0, "", undefined, NaN

x = x || 1

Ostrożnie używaj tego, jeśli prawidłowa wartość dla xjest fałszywa, na przykład false, i chcesz ustawić wartość domyślną tylko wtedy, gdy xjest niezdefiniowana.
Joshua Pinter

4

Jeśli pracujesz z obiektami, możesz użyć destrukturyzacji (od ES6) w następujący sposób:

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

... ale nie zyskujesz nic poza zaakceptowaną odpowiedzią, z wyjątkiem zamieszania.


1
„ale nie zyskujesz nic poza zaakceptowaną odpowiedzią poza pomyłką” - fajnie. :)
lindes

Założę się, że ktoś potraktuje to jako powód do nienawiści do javascript
Volper


-1

Przypisanie Rubiego || = operator zwarcia. Można to sobie wyobrazić w ten sposób:

return a || a = b

Więc w javascript wygląda to bardzo podobnie:

return a || (a = b);

Wydaje się jednak, jak wskazano w komentarzach poniżej, że ta dosłowna forma rubinowa jest mniej wydajna niż standardowy idiom javascript a = a || b.

Dla odniesienia: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html


1
W praktyce wydaje się, że a = a || bforma jest bardziej optymalna jsperf.com/x-or-x-equals-0-vs-x-equals-x-or-0/3
jchook

ah fajne narzędzie. jak to wygląda, jeśli x ma wartość, a więc zwarcia?
chris

Uważam, że porzucenie musi być jawne w jsperf, więc ten test powinien pokazać wydajność zwarcia. Domyślam się, że V8 ma specjalną optymalizację formy a = a || b.
jchook

3
FYI Wygląda na to, że wszelkie różnice zostały już zoptymalizowane.
Charles Wood

a || (a = b)ma poprawną semantykę do wnioskowania nazw funkcji. Obecnie trwa dyskusja nad nowym wnioskiem.
user4642212

-1

Możesz osiągnąć pożądane zachowanie za pomocą operatora | = w javascript tylko dla liczb całkowitych. Ale najpierw musisz zdefiniować zmienną.

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

Do obiektów

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

Dla tablic

let arr = []
arr[0] |= 100
console.log(arr) // [100]

Pytanie nie dotyczy |ani |=. Pożądane zachowanie w pytaniu nie jest związane z operacjami bitowymi.
user4642212

Masz rację, odpowiednio zmodyfikuję odpowiedź
wallgeek

Edytowano. Mam nadzieję, że teraz ma to sens.
wallgeek
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.