Ruby || = (o uguale a) in JavaScript?


128

Adoro il ||=meccanismo di Ruby . Se una variabile non esiste o è nil, creala e impostala uguale a qualcosa:

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

Adesso devo fare qualcosa di simile in JavaScript. Qual è la convenzione o il modo corretto per farlo? So che ||=non è una sintassi valida. 2 modi ovvi per gestirlo sono:

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

// or

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

Risposte:


152

Entrambi sono assolutamente corretti, ma se stai cercando qualcosa che funzioni come ||=in Ruby. Il primo metodo che è variable = variable || {}quello che stai cercando :)


1
Attento a usarlo se un valore valido per xè falso, come false, e vuoi solo impostare un valore predefinito quando xnon è definito.
Joshua Pinter

il commento sopra è giusto. Prendendo il tuo caso di esempio, non funzionerà allo stesso modo in JS. let amount = 0;seguito da amount = amount || 5 cambierà l'importo in 5. Se non vuoi che ciò accada, usa l' ??operatore invece di ||.
AshwinKumarS

@AshwinKumarS O semplicemente usa amount ??= 5;.
user4642212

@ user4642212 Non penso che la sintassi funzioni in JS, vero?
AshwinKumarS

@AshwinKumarS Sì, lo fa. Vedi la documentazione , le specifiche , la proposta .
user4642212

22

È possibile utilizzare l'operatore OR logico ||che valuta il suo operando destro se lValè un valore falso.

I valori di falsità includono ad es null, false, 0, "", undefined, NaN

x = x || 1

Attento a usarlo se un valore valido per xè falso, come false, e vuoi solo impostare un valore predefinito quando xnon è definito.
Joshua Pinter

4

Se stai lavorando con oggetti, puoi usare la destrutturazione (da ES6) in questo modo:

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

... ma non guadagni nulla dalla risposta accettata tranne la confusione.


1
"ma non guadagni nulla sulla risposta accettata tranne la confusione" - bello. :)
Lindes

Scommetto che qualcuno lo considererà un motivo per odiare javascript
Volper


-1

Ruby || = assegnazione dell'operatore in cortocircuito. Può essere pensato in questo modo:

return a || a = b

Quindi in javascript, questo sembra molto simile:

return a || (a = b);

Tuttavia, come sottolineato nei commenti di seguito, questa forma letterale ruby ​​è meno efficiente dell'idioma javascript standard a = a || b.

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


1
In pratica sembra che la a = a || bforma sia più ottimale jsperf.com/x-or-x-equals-0-vs-x-equals-x-or-0/3
jchook

ah fantastico strumento. che aspetto ha se x ha un valore e quindi cortocircuiti?
chris

Credo che lo smontaggio debba essere esplicito su jsperf, quindi questo test dovrebbe mostrare le prestazioni di cortocircuito. La mia ipotesi è che V8 abbia un'ottimizzazione speciale per la forma a = a || b.
jchook

3
Cordiali saluti, sembra che qualunque differenza c'era ora è stata ottimizzata.
Charles Wood

a || (a = b)ha la semantica corretta per dedurre i nomi delle funzioni. È attualmente in discussione la nuova proposta.
user4642212

-1

È possibile ottenere il comportamento desiderato utilizzando l'operatore | = in JavaScript solo per i numeri interi. Ma devi prima definire la variabile.

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

Per gli oggetti

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

Per array

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

La domanda non riguarda |o |=. Il comportamento desiderato nella domanda non è correlato alle operazioni bit per bit.
user4642212

Hai ragione, modifico la risposta di conseguenza
wallgeek

Modificato. Spero che ora abbia senso.
wallgeek
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.