web-dev-qa-db-fra.com

Qu'est-ce que la construction x = x || tu veux dire?

Je suis en train de déboguer du JavaScript et je ne peux pas expliquer ce que fait ce ||?

function (title, msg) {
  var title = title || 'Error';
  var msg   = msg || 'Error on Request';
}

Quelqu'un peut-il me donner un indice, pourquoi ce gars utilise var title = title || 'ERROR'? Je le vois parfois sans déclaration var.

221
opHASnoNAME

Cela signifie que l'argument title est facultatif. Donc, si vous appelez la méthode sans argument, elle utilisera une valeur par défaut de "Error".

C'est un raccourci pour l'écriture:

if (!title) {
  title = "Error";
}

Ce type de raccourci avec des expressions booléennes est également courant en Perl. Avec l'expression:

a OR b

il est évalué à true si a ou b est true. Donc, si a est vrai, vous n'avez pas du tout besoin de vérifier b. C'est ce qu'on appelle l'évaluation booléenne en court-circuit.

var title = title || "Error";

vérifie fondamentalement si title est évalué à false. Si c'est le cas, il "retourne" "Error", sinon il retourne title.

190
cletus

Quel est l'opérateur double pipe (||)?

L'opérateur à double pipe (||) est l'opérateur logique OR. Dans la plupart des langues , cela fonctionne de la manière suivante:

  • Si la première valeur est false, la seconde valeur est vérifiée. Si c'est true, il retourne true et si c'est false, il retourne false.
  • Si la première valeur est true, elle retourne toujours true, quelle que soit la seconde valeur.

Donc, fondamentalement, cela fonctionne comme cette fonction:

function or(x, y) {
  if (x) {
    return true;
  } else if (y) {
    return true;
  } else {
    return false;
  }
}

Si vous ne comprenez toujours pas, regardez ce tableau:

      | true   false  
------+---------------
true  | true   true   
false | true   false  

En d'autres termes, ce n'est faux que lorsque les deux valeurs sont fausses.

En quoi est-ce différent en JavaScript?

JavaScript est un peu différent, car c'est un langage faiblement typé . Dans ce cas, cela signifie que vous pouvez utiliser l'opérateur || avec des valeurs qui ne sont pas des booléens. Bien que cela n’ait aucun sens, vous pouvez utiliser cet opérateur avec par exemple une fonction et un objet:

(function(){}) || {}

Que se passe-t-il là?

Si les valeurs ne sont pas booléennes, JavaScript transforme une conversation implicite en booléen . Cela signifie que si la valeur est falsey (par exemple, 0, "", null, undefined (voir aussi toutes les valeurs Falsey en JavaScript )), elle sera traitée comme false; sinon, il est traité comme true.

Ainsi, l'exemple ci-dessus devrait donner true, car la fonction vide est la vérité. Eh bien, ça ne va pas. Il retourne la fonction vide. En effet, l'opérateur || de JavaScript ne fonctionne pas comme je l'avais écrit au début. Cela fonctionne de la manière suivante:

  • Si la première valeur est falsey , elle renvoie la deuxième valeur .
  • Si la première valeur est vérité , elle renvoie la première valeur .

Surpris? En fait, il est "compatible" avec l'opérateur || traditionnel. Cela pourrait être écrit comme la fonction suivante:

function or(x, y) {
  if (x) {
    return x;
  } else {
    return y;
  }
}

Si vous passez une valeur de vérité sous la forme x, il retourne x, c'est-à-dire une valeur de vérité. Donc, si vous l'utilisez plus tard dans la clause if:

(function(x, y) {
  var eitherXorY = x || y;
  if (eitherXorY) {
    console.log("Either x or y is truthy.");
  } else {
    console.log("Neither x nor y is truthy");
  }
}(true/*, undefined*/));

vous obtenez "Either x or y is truthy.".

Si x était falsey, eitherXorY serait y. Dans ce cas, vous obtiendrez le "Either x or y is truthy." si y était une vérité; sinon, vous obtiendrez "Neither x nor y is truthy".

La vraie question

Maintenant, quand vous savez comment fonctionne l'opérateur ||, vous pouvez probablement comprendre par vous-même ce que signifie x = x || y. Si x est la vérité, x est affecté à x, il ne se passe donc rien; sinon, y est affecté à x. Il est couramment utilisé pour définir des paramètres par défaut dans les fonctions. Cependant, cela est souvent considéré comme une mauvaise pratique de programmation , car il vous empêche de passer une valeur de Falsey (qui n'est pas nécessairement undefined ou null) en tant que paramètre. Considérez l'exemple suivant:

function badFunction(/* boolean */flagA) {
  flagA = flagA || true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

Cela semble valable à première vue. Cependant, que se passerait-il si vous passiez false en tant que paramètre flagA (puisqu'il est booléen, c’est-à-dire que vous pouvez être true ou false)? Il deviendrait true. Dans cet exemple, il n’existe aucun moyen de définir flagA sur false.

Ce serait une meilleure idée de vérifier explicitement si flagA est undefined, comme ça:

function goodFunction(/* boolean */flagA) {
  flagA = typeof flagA !== "undefined" ? flagA : true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

Bien que ce soit plus long, cela fonctionne toujours et est plus facile à comprendre.


Vous pouvez également utiliser la syntaxe ES6 pour les paramètres de fonction par défaut , mais notez que cela ne fonctionne pas dans les navigateurs plus anciens (comme IE). Si vous voulez supporter ces navigateurs, vous devez transpiler votre code avec Babel .

Voir aussi Opérateurs logiques sur le MDN .

174

Si le titre n'est pas défini, utilisez "ERROR" comme valeur par défaut.

Plus générique:

var foobar = foo || default;

Lit: réglez foobar sur foo ou default. Vous pouvez même enchaîner cela plusieurs fois:

var foobar = foo || bar || something || 42;
28
ericteubert

Expliquer cela un peu plus ...

L'opérateur || est l'opérateur logique_or. Le résultat est vrai si la première partie est vraie et c'est vrai si la deuxième partie est vraie et c'est vrai si les deux parties sont vraies. Pour plus de clarté, le voici dans un tableau:

 X | Y | X || Y 
---+---+--------
 F | F |   F    
---+---+--------
 F | T |   T    
---+---+--------
 T | F |   T    
---+---+--------
 T | T |   T    
---+---+--------

Maintenant, remarquez quelque chose ici? Si X est vrai, le résultat est toujours vrai. Donc, si nous savons que X est vrai, nous n'avons pas du tout à vérifier Y. Beaucoup de langages implémentent donc des évaluateurs "en court-circuit" pour logiques_or (et logiques_and venant de l'autre sens). Ils vérifient le premier élément et si c'est vrai, ils ne se soucient pas du tout de vérifier le second. Le résultat (en termes logiques) est identique, mais en termes d'exécution, la différence est potentiellement énorme si le deuxième élément est coûteux à calculer.

Alors, qu'est-ce que cela a à voir avec votre exemple?

var title   = title || 'Error';

Regardons ça. L'élément title est transmis à votre fonction. En JavaScript, si vous ne transmettez pas de paramètre, la valeur par défaut est NULL. Également en JavaScript si votre variable est une valeur nulle, elle est considérée comme fausse par les opérateurs logiques. Donc si cette fonction est appelée avec un titre donné, c'est une valeur non fausse et donc assignée à la variable locale. Si, toutefois, aucune valeur ne lui est attribuée, il s'agit d'une valeur nulle et donc fausse. L'opérateur logical -or évalue ensuite la deuxième expression et renvoie "Erreur" à la place. Alors maintenant, la variable locale reçoit la valeur 'Error'.

Cela fonctionne à cause de l'implémentation d'expressions logiques en JavaScript. Il ne retourne pas une valeur booléenne correcte (true ou false) mais renvoie la valeur qui lui a été donnée sous certaines règles indiquant ce qui est considéré équivalent à true et ce qui est considéré équivalent à false. Recherchez votre référence JavaScript pour savoir ce que JavaScript considère comme étant vrai ou faux dans des contextes booléens.

Fondamentalement, il vérifie si la valeur avant le || est évalué à true, si oui, il prend cette valeur, sinon, il prend la valeur après le ||.

Valeurs pour lesquelles il prendra la valeur après le || (Autant que je m'en souvienne):

  • undefined
  • false
  • '' (Chaîne null ou null)
7
Morfildur

Le double tuyau signifie "OU" logique. Ce n'est pas vraiment le cas lorsque le "paramètre non défini", puisque strictement en javascript si vous avez un code comme celui-ci:

function foo(par) {
}

Puis appelle

foo()
foo("")
foo(null)
foo(undefined)
foo(0)

ne sont pas équivalents.

Double pipe (||) jettera le premier argument en boolean et si boolean est vrai, exécutez l'affectation, sinon la partie droite sera affectée.

Ceci est important si vous vérifiez le paramètre non défini.

Disons que nous avons une fonction setSalary qui a un paramètre optionnel. Si l'utilisateur ne fournit pas le paramètre, la valeur par défaut de 10 doit être utilisée.

si vous faites le chèque comme ceci:

function setSalary(dollars) {
    salary = dollars || 10
}

Cela donnera un résultat inattendu sur appel comme

setSalary(0) 

Il faudra toujours régler le 10 suivant le flux décrit ci-dessus.

7
Juriy

Pour ajouter quelques explications à tout ce qui a été dit avant moi, je devrais vous donner quelques exemples pour comprendre les concepts logiques.

var name = false || "Mohsen"; # name equals to Mohsen
var family = true || "Alizadeh" # family equals to true

Cela signifie que si le côté gauche est évalué comme une déclaration vraie, il sera terminé et le côté gauche sera renvoyé et affecté à la variable. dans d'autres cas, le côté droit sera renvoyé et attribué.

Et opérateur ont la structure opposée comme ci-dessous.

var name = false && "Mohsen" # name equals to false
var family = true && "Alizadeh" # family equals to Alizadeh
4
Mohsen Alizadeh

double opérateur

cet exemple est-il utile?

var section = document.getElementById('special');
if(!section){
     section = document.getElementById('main');
}

peut également être

var section = document.getElementById('special') || document.getElementById('main');
4
choise

Bien que réponse de Cletus soit correct, j'estime qu'il faudrait ajouter davantage de détails en ce qui concerne "est évalué à faux" en JavaScript.

var title = title || 'Error';
var msg   = msg || 'Error on Request';

N’est pas seulement en train de vérifier si title/msg a été fourni, mais aussi si l’un d’eux est falsy . c'est-à-dire l'un des suivants:

  • faux.
  • 0 (zero)
  • "" (chaîne vide)
  • nul.
  • indéfini.
  • NaN (une valeur numérique spéciale signifiant Non-un-nombre!)

Donc dans la ligne

var title = title || 'Error';

Si title est true (c'est-à-dire pas faux, donc title = "titleMessage" etc.), alors l'opérateur booléen OR (||) a trouvé une valeur "vraie", ce qui signifie qu'elle est vraie, donc il court-circuite et renvoie la valeur vraie (titre).

Si title est faux (c'est-à-dire l'une des listes ci-dessus), l'opérateur booléen OR (||) a trouvé une valeur 'false' et doit maintenant évaluer l'autre partie de l'opérateur, 'Erreur ', qui a la valeur true et est donc renvoyé.

Il semblerait également (après une expérimentation rapide de la console Firebug) que si les deux côtés de l'opérateur sont évalués à false, le deuxième opérateur "falsy" est renvoyé.

c'est à dire.

return ("" || undefined)

renvoie undefined, c'est probablement pour vous permettre d'utiliser le comportement évoqué dans cette question lorsque vous essayez d'utiliser le titre/message par défaut à "". c'est-à-dire après avoir couru

var foo = undefined
foo = foo || ""

foo serait réglé sur ""

4
Azrantha

Citation: "Qu'est-ce que la construction x = x || y signifie?"

attribution d'une valeur par défaut.

Cela signifie fournir une valeur par défaut de y à x , au cas où x attend toujours sa valeur mais ne l'a pas encore reçue ou a été délibérément omis dans afin de retomber sur un défaut.

2
Bekim Bacaj