373 votes

Explication de l'affectation des variables OR (||) en JavaScript

Étant donné ce bout de JavaScript...

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f = a || b || c || d || e;

alert(f); // 4

Quelqu'un peut-il m'expliquer comment s'appelle cette technique (ma meilleure supposition est dans le titre de cette question !)? Et comment/pourquoi elle fonctionne exactement ?

Si je comprends bien, la variable f se verra attribuer la valeur la plus proche (de gauche à droite) de la première variable dont la valeur n'est ni nulle ni indéfinie, mais je n'ai pas réussi à trouver beaucoup de matériel de référence sur cette technique et je l'ai vue utilisée à plusieurs reprises.

Par ailleurs, cette technique est-elle spécifique à JavaScript ? Je sais que si l'on fait quelque chose de similaire en PHP, on obtient les résultats suivants f ayant une valeur booléenne vraie, plutôt qu'une valeur de d lui-même.

230voto

unwind Points 181987

Véase évaluation des courts-circuits pour l'explication. C'est une façon courante d'implémenter ces opérateurs ; elle n'est pas propre à JavaScript.

58 votes

Tenez compte du fait que le dernier sera toujours affecté, même s'il est indéfini, nul ou faux. Mettre quelque chose dont vous savez qu'il n'est pas faux, nul ou indéfini à la fin de la chaîne est un bon moyen de signaler que rien n'a été trouvé.

0 votes

Je connais cette technique depuis des années, mais ce qui m'a frappé lorsque j'ai voulu l'utiliser, c'est que le résultat de l'expression n'est pas converti en booléen. Vous ne pouvez pas faire plus tard if( true == f ) . Si un nombre entier a été stocké dans f, alors ce test retournera toujours false.

9 votes

En fait, vous pouvez faire if(true == f) qui est identique à if(f) : le test réussira. Si vous voulez également tester le type de f utiliser une comparaison stricte : if(true === f) qui échouera en effet.

52voto

Alsciende Points 11508

Les variables Javascript ne sont pas typées, donc f peut se voir attribuer une valeur entière même si elle a été attribuée par des opérateurs booléens.

f se voit attribuer la valeur la plus proche qui est non équivalent à faux . Ainsi, 0, false, null, undefined, sont tous transmis :

alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'

13 votes

N'oubliez pas '' est également égal à faux dans ce cas.

0 votes

Upvote pour avoir souligné que f is assigned the NEAREST value ce qui est un point assez important ici.

3 votes

"Le plus proche" n'est pas tout à fait vrai, bien qu'il en ait l'apparence. Le booléen || L'opérateur, qui est un opérateur booléen, a deux opérandes : un côté gauche et un côté droit. Si le côté gauche de l'opérateur || es véridique l'opération se résout sur le côté gauche et le côté droit est ignoré. Si le côté gauche est falsy il se résout au côté droit. Donc null || undefined || 4 || 0 se résout en fait à undefined || 4 || 0 qui se résume à 4 || 0 qui se résume à 4 .

32voto

Marcin Points 3884

Il n'y a pas de magie. Les expressions booléennes comme a || b || c || d sont évalués paresseusement. Interpeter recherche la valeur de a c'est indéfini donc c'est faux donc il passe à autre chose, puis il voit b qui est nulle, ce qui donne toujours un faux résultat, donc il continue, puis il voit c - même histoire. Finalement, il voit d et dit 'huh, ce n'est pas nul, donc j'ai mon résultat' et il l'assigne à la variable finale.

Cette astuce fonctionnera dans tous les langages dynamiques qui font une évaluation paresseuse en circuit court des expressions booléennes. Dans les langages statiques, elle ne compilera pas (erreur de type). Dans les langages qui sont avides d'évaluer les expressions booléennes, elle retournera une valeur logique (i.e. true dans ce cas).

6 votes

Dans le langage statique C#, on peut utiliser l'opérateur ? ? à la manière de : object f = a ? ? b ? ? c ? ? d ? ? e ;

2 votes

Herzmeister - merci ! Je ne savais pas que l'opérateur ? ? pouvait être enchaîné en C# et utilisé dans des techniques d'évaluation paresseuses.

3 votes

Comme mentionné ailleurs, ce dernier d sera attribué, qu'il ait été nul/indéfini ou non.

10voto

WSimpson Points 11

Cette question a déjà reçu plusieurs bonnes réponses.

En résumé, cette technique tire parti d'une caractéristique de la façon dont le langage est compilé. En effet, JavaScript "court-circuite" l'évaluation des opérateurs booléens et renvoie la valeur associée à la première valeur de variable non fausse ou à ce que contient la dernière variable. Voir l'explication d'Anurag sur les valeurs qui seront évaluées comme fausses.

L'utilisation de cette technique n'est cependant pas une bonne pratique pour plusieurs raisons.

  1. Lisibilité du code : Ceci utilise des opérateurs booléens, et si le comportement de la compilation n'est pas compris, le résultat attendu sera une valeur booléenne.

  2. Stabilité : Il s'agit de l'utilisation d'une caractéristique de la façon dont le langage est compilé qui est incohérente dans plusieurs langues, et pour cette raison, c'est quelque chose qui pourrait potentiellement être ciblé pour un changement à l'avenir.

  3. Caractéristiques documentées : Il existe une alternative qui répond à ce besoin et qui est cohérente dans un plus grand nombre de langues. Il s'agit de l'opérateur ternaire :

    () ? valeur 1 : valeur 2.

L'utilisation de l'opérateur ternaire nécessite un peu plus de saisie, mais il fait clairement la distinction entre l'expression booléenne évaluée et la valeur attribuée. En outre, il peut être enchaîné, ce qui permet de recréer les types d'affectations par défaut effectuées ci-dessus.

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f =  ( a ) ? a : 
                ( b ) ? b :
                       ( c ) ? c :
                              ( d ) ? d :
                                      e;

alert(f); // 4

8voto

Arshid KV Points 5175

Sortie de retour première valeur vraie .

Si toutes les valeurs sont fausses, la dernière valeur fausse est retournée.

Exemple:-

  null || undefined || false || 0 || 'apple'  // Return apple

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X