Ruby || = (ou igual) em JavaScript?

128

Eu amo o ||=mecanismo de Ruby . Se uma variável não existir ou for nil, crie-a e defina-a como algo:

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

Eu preciso fazer algo semelhante em JavaScript agora. Qual é a convenção ou a maneira correta de fazer isso? Eu sei que ||=não é uma sintaxe válida. 2 maneiras óbvias de lidar com isso são:

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

// or

if (!window.myLib)
  window.myLib = {};
às.
fonte

Respostas:

152

Ambos estão absolutamente corretos, mas se você estiver procurando por algo que funcione como ||=em rubi. O primeiro método variable = variable || {}é o que você está procurando :)

Dzung Nguyen
fonte
Cuidado ao usar isso se um valor válido para xfor falso, como false, e você desejar definir um padrão quando xindefinido.
Joshua Pinter
22

Você pode usar o operador OR lógico ||que avalia seu operando correto se lValfor um valor falso.

Os valores de falsidade incluem, por exemplo, null, false, 0, "", undefined, NaN

x = x || 1
Moritz Roessler
fonte
Cuidado ao usar isso se um valor válido para xfor falso, como false, e você desejar definir um padrão quando xindefinido.
Joshua Pinter
4

Se você estiver trabalhando com objetos, poderá usar a desestruturação (desde o ES6) da seguinte forma:

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

... mas você não ganha nada sobre a resposta aceita, exceto confusão.

Inkling
fonte
1
"mas você não ganha nada sobre a resposta aceita, exceto confusão" - legal. :)
lindes 7/04
Aposto que alguém vai levar isso como uma razão para odiar javascript
Volper
1

O operador que você perguntou foi proposto como um recurso em JavaScript . Atualmente , ele está no Estágio 3 , portanto ainda não é uma parte oficial do idioma, mas será aceito, com alterações mínimas se descobrirem grandes problemas inesperados.

Agora você pode usá-lo usando o plug-in Babel plugin-proposta-lógica-atribuição-operadores . Eu nunca usei esse plug-in, então não tenho idéia de como ele funciona.

Elias Zamaria
fonte
-1

Ruby || = atribuição de curto-circuito do operador. Pode-se pensar assim:

return a || a = b

Então, em javascript, isso parece muito semelhante:

return a || (a = b);

Parece, como indicado nos comentários abaixo, no entanto, que esse formato literal de rubi é menos eficiente que o idioma javascript padrão a = a || b.

Para referência: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html

chris
fonte
1
Na prática, parece que a a = a || bforma é mais ideal jsperf.com/x-or-x-equals-0-vs-x-equals-x-or-0/3
jchook
ah ferramenta legal. como é se x tem um valor e tem um curto-circuito?
chris
Acredito que a desmontagem precisa ser explícita no jsperf, portanto, este teste deve mostrar o desempenho do curto-circuito. Meu palpite é que o V8 tem uma otimização especial para o formulário a = a || b.
jchook
3
Para sua informação, parece que qualquer diferença que tenha sido agora foi otimizada.
Charles Wood
a || (a = b)possui a semântica correta para inferir nomes de funções. Está atualmente em discussão para a nova proposta.
user4642212
-1

Você pode obter o comportamento desejado usando o operador | = em javascript apenas para números inteiros. Mas você precisa definir a variável primeiro.

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

Para objetos

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

Para matrizes

let arr = []
arr[0] |= 100
console.log(arr) // [100]
wallgeek
fonte
A questão não é sobre |ou |=. O comportamento desejado na pergunta não está relacionado às operações bit a bit.
user4642212 16/07
Você está certo, eu vou editar a resposta de acordo.
wallgeek 16/07
Editado. Espero que faça sentido agora.
wallgeek