Ruby || = (ou égal) en JavaScript?


128

J'adore le ||=mécanisme de Ruby . Si une variable n'existe pas ou existe nil, créez-la et définissez-la égale à quelque chose:

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

Je dois faire quelque chose de similaire en JavaScript maintenant. Quelle est la convention ou la bonne façon de procéder? Je sais ||=que la syntaxe n'est pas valide. 2 façons évidentes de le gérer sont:

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

// or

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

Réponses:


152

Les deux sont tout à fait corrects, mais si vous cherchez quelque chose qui fonctionne comme ||=dans le rubis. La première méthode qui est variable = variable || {}celle que vous recherchez :)


1
Attention à utiliser ceci si une valeur valide pour xest fausse, comme false, et que vous ne voulez définir une valeur par défaut que lorsque xn'est pas défini.
Joshua Pinter le

le commentaire ci-dessus est juste. En prenant votre exemple, cela ne fonctionnera pas de la même manière dans JS. let amount = 0;suivi de amount = amount || 5 changera le montant à 5. Si vous ne voulez pas que cela se produise, utilisez l' ??opérateur au lieu de ||.
AshwinKumarS

@AshwinKumarS Ou utilisez simplement amount ??= 5;.
user4642212

@ user4642212 Je ne pense pas que la syntaxe fonctionne dans JS, n'est-ce pas?
AshwinKumarS

@AshwinKumarS Oui, c'est vrai. Voir la documentation , le cahier des charges , la proposition .
user4642212

22

Vous pouvez utiliser l'opérateur logique OR ||qui évalue son opérande droit s'il lVals'agit d'une valeur erronée.

Les valeurs fausses incluent par exemple null, false, 0, "", undefined, NaN

x = x || 1

Attention à utiliser ceci si une valeur valide pour xest fausse, comme false, et que vous ne voulez définir une valeur par défaut que lorsque xn'est pas défini.
Joshua Pinter le

4

Si vous travaillez avec des objets, vous pouvez utiliser la déstructuration (depuis ES6) comme ceci:

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

... mais vous ne gagnez rien sur la réponse acceptée, sauf la confusion.


1
"mais vous ne gagnez rien sur la réponse acceptée, sauf la confusion" - bien. :)
lindes

Je parie que quelqu'un va prendre cela comme une raison de détester javascript
Volper

1

L'opérateur que vous avez interrogé a été proposé comme fonctionnalité dans JavaScript . Il est actuellement au stade 3 , donc ce n'est pas encore une partie officielle de la langue, mais il sera accepté, avec au plus des changements mineurs s'ils découvrent des problèmes majeurs inattendus.

Vous pouvez l'utiliser maintenant en utilisant le plugin Babel plugin-proposition-logical-assignment-operators . Je n'ai jamais utilisé ce plugin, donc je n'ai aucune idée de son fonctionnement.


-1

Ruby || = affectation des courts-circuits de l'opérateur. Cela peut être considéré comme ceci:

return a || a = b

Donc, en javascript, cela semble très similaire:

return a || (a = b);

Il semble cependant, comme indiqué dans les commentaires ci-dessous, que cette forme rubis littérale est moins efficace que l'idiome javascript standard a = a || b.

Pour référence: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html


1
En pratique, il semble que la a = a || bforme soit plus optimale jsperf.com/x-or-x-equals-0-vs-x-equals-x-or-0/3
jchook

ah outil cool. à quoi cela ressemble-t-il si x a une valeur et donc des courts-circuits?
chris

Je pense que le démontage doit être explicite sur jsperf, donc ce test devrait montrer les performances de court-circuit. Je suppose que V8 a une optimisation spéciale pour la forme a = a || b.
jchook

3
FYI Il semble que la différence qui existait a maintenant été optimisée.
Charles Wood

a || (a = b)a la sémantique correcte pour déduire les noms de fonctions. Il est actuellement en discussion pour la nouvelle proposition.
user4642212

-1

Vous pouvez obtenir le comportement souhaité en utilisant l'opérateur | = en javascript pour les entiers uniquement. Mais vous devez d'abord définir la variable.

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

Pour les objets

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

Pour les tableaux

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

La question ne concerne pas |ou |=. Le comportement souhaité dans la question n'est pas lié aux opérations au niveau du bit.
user4642212

Vous avez raison, je modifierai la réponse en conséquence
wallgeek

Édité. J'espère que cela a du sens maintenant.
wallgeek
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.