web-dev-qa-db-fra.com

JavaScript OR (||) explication d'affectation de variable

Compte tenu de cet extrait 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 s'il vous plaît comment s'appelle cette technique (ma meilleure hypothèse est dans le titre de cette question!)? Et comment/pourquoi cela fonctionne exactement?

Je crois comprendre que 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 documents de référence. à propos de cette technique et ont vu il utilisé beaucoup.

De plus, cette technique est-elle spécifique à JavaScript? Je sais que faire quelque chose de similaire dans PHP aurait pour résultat que f aura une vraie valeur booléenne, plutôt que la valeur de d lui-même.

326
chattsm

Voir évaluation de court-circuit pour l'explication. C'est une manière courante d'implémenter ces opérateurs. ce n'est pas unique à JavaScript.

198
unwind

Ceci est fait pour assigner un valeur par défaut, dans ce cas la valeur de y, si la variable x est falsy.

Les opérateurs booléens en JavaScript peuvent renvoyer un opérande, et pas toujours un résultat booléen comme dans d'autres langues.

L'opérateur logique OR (||) renvoie la valeur de son deuxième opérande, si le premier est faux, sinon la valeur du premier opérande est renvoyée.

Par exemple:

"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"

Les valeurs Falsy sont celles qui contraignent à false lorsqu'elles sont utilisées dans un contexte booléen, et elles sont 0, null, undefined, une chaîne vide, NaN et bien sûr false.

172
CMS

Javacript utilise évaluation de court-circuit pour les opérateurs logiques || et &&. Cependant, il diffère des autres langues en ce sens qu'il renvoie le résultat de la dernière valeur qui a interrompu l'exécution, à la place d'une valeur true ou false.

Les valeurs suivantes sont considérées comme fausseté en JavaScript.

  • false
  • nul
  • "" (chaîne vide)
  • Nan
  • undefined

En ignorant les règles priorité des opérateurs et en gardant les choses simples, les exemples suivants montrent quelle valeur a arrêté l'évaluation et est renvoyée en conséquence.

false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"

Les 5 premières valeurs jusqu’à NaN sont fausses, elles sont donc évaluées de gauche à droite, jusqu’à ce qu’elle atteigne la première valeur de vérité - "Hello", ce qui rend toute l’expression vraie, de sorte que rien de plus haut ne sera évalué. et "Hello" est renvoyé à la suite de l'expression. De même, dans ce cas:

1 && [] && {} && true && "World" && null && 2010 // null

Les 5 premières valeurs sont toutes véridiques et sont évaluées jusqu'à ce qu'elles répondent à la première valeur de fausseté (null), ce qui rend l'expression fausse. Ainsi, 2010 n'est plus évalué et null est renvoyé. à la suite de l'expression.

L'exemple que vous avez donné utilise cette propriété de JavaScript pour effectuer une tâche. Il peut être utilisé partout où vous devez obtenir la première valeur de vérité ou de fausseté parmi un ensemble de valeurs. Ce code ci-dessous affectera la valeur "Hello" à b, car il est plus facile d'attribuer une valeur par défaut au lieu d'effectuer des vérifications if-else.

var a = false;
var b = a || "Hello";

Vous pourriez appeler l'exemple ci-dessous une exploitation de cette fonctionnalité, ce qui rend le code plus difficile à lire.

var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);

Dans l'alerte, nous vérifions si messages est faux, et si oui, alors évaluer et renvoyer noNewMessagesText, sinon évaluer et renvoyer newMessagesText. Comme il s'agit de fausseté dans cet exemple, nous nous arrêtons à noNewMessagesText et alertons "Sorry, you have no new messages.".

153
Anurag

Les variables Javascript n'étant pas typées, une valeur entière peut être affectée à f même si elle a été affectée par le biais d'opérateurs booléens.

f se voit attribuer la valeur la plus proche qui est pas équivalent à false. Donc 0, false, null, indéfini, sont tous passés sur:

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

Il n'y a pas de magie à cela. Les expressions booléennes telles que a || b || c || d sont évaluées paresseusement. Interpeter cherche la valeur de a, elle est indéfinie, elle est donc fausse et continue, puis il voit b qui est nul, ce qui donne toujours un résultat faux et continue, puis il voit c - même histoire. Finalement, il voit d et dit 'hein, ce n'est pas nul, j'ai donc mon résultat' et il l'assigne à la variable finale.

Cette astuce fonctionnera dans tous les langages dynamiques qui évaluent par court-circuit des expressions booléennes. Dans les langages statiques, il ne sera pas compilé (erreur de type). Dans les langages désireux d'évaluer des expressions booléennes, cela renvoie une valeur logique (c'est-à-dire true dans ce cas).

29
Marcin

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

En résumé, cette technique tire parti d'une fonctionnalité de la compilation du langage. C'est-à-dire que 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 à la valeur de la dernière variable. Voir l'explication d'Anurag de ces valeurs qui donneront une valeur false.

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

  1. Lisibilité du code: il s'agit d'opérateurs booléens. Si le comportement de la compilation n'est pas compris, le résultat attendu est une valeur booléenne.
  2. Stabilité: Cela utilise une fonctionnalité incohérente de la manière dont la langue est compilée dans plusieurs langues et qui, de ce fait, pourrait potentiellement être ciblée pour être modifiée à l'avenir.
  3. Fonctionnalités documentées: il existe une alternative qui répond à ce besoin et est cohérente dans plusieurs langues. Ce serait l'opérateur ternaire:

    ()? valeur 1: valeur 2.

L'utilisation de l'opérateur ternaire nécessite un peu plus de frappe, mais elle distingue clairement l'expression booléenne évaluée et la valeur attribuée. En outre, il peut être chaîné, de sorte que les types d’assignations par défaut effectuées ci-dessus puissent être recréés.

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
8
WSimpson

Renvoie la sortie première valeur vraie.

Si tous sont faux, renvoyer la dernière valeur fausse.

Exemple:-

  null || undefined || false || 0 || 'Apple'  // Return Apple
5
Arshid KV

Il s'agit de définir la nouvelle variable (z) sur la valeur de x s'il s'agit de "vérité" (différent de zéro, objet/tableau/fonction valide, quel qu'il soit) ou y autrement. C'est un moyen relativement courant de fournir une valeur par défaut au cas où x n'existerait pas.

Par exemple, si vous avez une fonction qui prend un paramètre de rappel facultatif, vous pouvez fournir un rappel par défaut qui ne fait rien:

function doSomething(data, callback) {
    callback = callback || function() {};
    // do stuff with data
    callback(); // callback will always exist
}
4
Matthew Crumley

Son appelé opérateur de court-circuit.

L’évaluation du court-circuit indique que le deuxième argument est exécuté ou évalué uniquement si le premier argument ne suffit pas pour déterminer la valeur de l’expression. lorsque le premier argument de la fonction OR (||) est évalué à true, la valeur globale doit être true.

Il pourrait également être utilisé pour définir une valeur par défaut pour l'argument de la fonction.

function theSameOldFoo(name){ 
  name = name || 'Bar' ;
  console.log("My best friend's name is " + name);
}
theSameOldFoo();  // My best friend's name is Bar
theSameOldFoo('Bhaskar');  // My best friend's name is Bhaskar`
1
Vijay

Cela signifie que si x est défini, la valeur de z sera x, sinon, si y est défini, sa valeur sera définie comme les z valeur.

c'est pareil que

if(x)
  z = x;
else
  z = y;

C'est possible car les opérateurs logiques en JavaScript ne renvoient pas de valeurs booléennes, mais la valeur du dernier élément nécessaire à la finalisation de l'opération (dans une phrase OR, il s'agirait de la première valeur non fausse, dans une phrase AND ce serait le dernier). Si l'opération échoue, alors false est renvoyé.

1
Andris

Il évaluera X et, si X n'est pas nul, la chaîne vide ou 0 (logique faux), il l'attribuera à z. Si X est nul, la chaîne vide ou 0 (logique faux), il affectera y à z.

var x = '';
var y = 'bob';
var z = x || y;
alert(z);

Sortie 'bob'

0
tvanfosson

Selon le blog de Bill Higgins post; idiome d'assignation OR logique logique (février 2007), ce comportement est vrai à partir de la v1.2 (au moins)

Il suggère également une autre utilisation (citée): " normalisation légère des différences entre navigateurs "

// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;
0
Alon Brontman