Qu'est-ce que la construction x = x || y signifie?
-
25-09-2019 - |
Question
Je suis en train de déboguer du JavaScript et je ne peux pas expliquer ce que c'est ||
fait?
function (title, msg) {
var title = title || 'Error';
var msg = msg || 'Error on Request';
}
Quelqu'un peut-il me donner un indice sur la raison pour laquelle ce type utilise var title = title || 'ERROR'
?Je le vois parfois sans var
déclaration également.
La solution
Cela signifie que l'argument title
est facultative. Donc, si vous appelez la méthode sans argument, il utilisera une valeur par défaut de "Error"
.
Il est un raccourci pour l'écriture:
if (!title) {
title = "Error";
}
Ce genre de truc avec un raccourci des expressions booléennes est commune en Perl aussi. Avec l'expression:
a OR b
il évalue à true
si l'a
ou b
est true
. Donc, si a
est vrai que vous n'avez pas besoin de vérifier b
du tout. On appelle cela l'évaluation booléenne court-circuit si:
var title = title || "Error";
vérifie essentiellement si title
évalue à false
. Dans le cas contraire, il "renvoie" "Error"
, sinon il retourne title
.
Autres conseils
Quel est l'opérateur double tube (de ||
)?
L'opérateur lit double de tuyau (||
) est la logique opérateur OR
. Dans la plupart des langues il fonctionne de la manière suivante:
- Si la première valeur est
false
, il vérifie la deuxième valeur. Si c'esttrue
, elle retournetrue
et si elle estfalse
, elle retournefalse
. - Si la première valeur est
true
, il retourne toujourstrue
, peu importe ce que la deuxième valeur est.
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, il est faux que lorsque les deux valeurs sont fausses.
Comment est-il différent en JavaScript?
JavaScript est un peu différent, car il est un langage faiblement typé . Dans ce cas, cela signifie que vous pouvez utiliser l'opérateur de ||
avec des valeurs qui ne sont pas booléens. Bien que cela n'a aucun sens, vous pouvez utiliser cet opérateur avec par exemple une fonction et un objet:
(function(){}) || {}
Que se passe-il?
Si les valeurs ne sont pas booléen, JavaScript rend la conversation implicite booléen . Cela signifie que si la valeur est Falsey (par exemple 0
, ""
, null
, undefined
(voir aussi Tous Falsey valeurs JavaScript )), il sera traité comme false
; sinon il est traité comme true
.
Ainsi, l'exemple ci-dessus devrait donner true
, parce que la fonction est vide truthy. Eh bien, il ne fonctionne pas. Elle retourne la fonction vide. En effet, l'opérateur ||
de JavaScript ne fonctionne pas comme je l'ai écrit au début. Il fonctionne de la manière suivante:
- Si la première valeur est Falsey , il retourne la seconde valeur .
- Si la première valeur est truthy , il retourne la première valeur .
Surpris? En fait, il est « compatible » avec l'opérateur ||
traditionnel. Il pourrait être écrit en fonction suivante:
function or(x, y) {
if (x) {
return x;
} else {
return y;
}
}
Si vous passez une valeur truthy comme x
, il retourne x
, qui est une valeur truthy. 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 obtenez le "Either x or y is truthy."
si y
était truthy; sinon vous obtiendrez "Neither x nor y is truthy"
.
La question réelle
Maintenant, quand vous savez comment opérateur ||
fonctionne, vous pouvez probablement faire par vous-même ce que fait x = x || y
signifie. Si x
est truthy, x
est affecté à x
, donc en fait rien ne se passe; autrement y
est affecté à x
. Il est couramment utilisé pour définir les paramètres par défaut des fonctions. Cependant, il est souvent considéré comme une pratique de programmation mauvais , car il vous empêche de passer une valeur Falsey (qui est pas nécessairement undefined
ou null
) en tant que paramètre. Considérons exemple suivant:
function badFunction(/* boolean */flagA) {
flagA = flagA || true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
Il semble valide à première vue. Cependant, ce qui se passerait si vous avez passé false
comme paramètre flagA
(car il est booléen, à savoir peut être true
ou false
)? Il deviendrait true
. Dans cet exemple, il n'y a aucun moyen de définir flagA
à false
.
Il 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 qu'il soit plus, il fonctionne toujours et il est plus facile à comprendre.
Vous pouvez également utiliser la syntaxe ES6 pour la fonction par défaut paramètres , mais notez que cela ne fonctionne pas dans les anciens navigateurs (comme IE). Si vous souhaitez soutenir ces navigateurs, vous devez transpile votre code avec Babel .
Voir aussi Opérateurs logiques sur MDN .
Si le titre n'est pas défini, utilisez « erreur » comme valeur par défaut.
Plus générique:
var foobar = foo || default;
lit comme suit: Set foobar à foo
ou default
.
Vous pouvez même enchaîner ce jusqu'à plusieurs fois:
var foobar = foo || bar || something || 42;
Expliquer cela un peu plus ...
L'opérateur est l'opérateur ||
-or
logique. Le résultat est vrai si la première partie est vrai et il est vrai si la deuxième partie est vrai et il est vrai que si les deux parties sont remplies. Pour plus de clarté, voici dans un tableau:
X | Y | X || Y
---+---+--------
F | F | F
---+---+--------
F | T | T
---+---+--------
T | F | T
---+---+--------
T | T | T
---+---+--------
Maintenant, remarquez quelque chose? Si X
est vrai, le résultat est toujours vrai. Donc, si nous savons que X
est vrai que nous ne devons pas vérifier Y
du tout. De nombreuses langues mettent en œuvre ainsi « court-circuit » pour les évaluateurs-or
logique (et and
logique venant de l'autre sens). Ils vérifient le premier élément et si cela est vrai qu'ils ne prennent pas la peine de vérifier la seconde du tout. Le résultat (en termes logiques) est le même, mais en termes d'exécution il y a potentiellement une énorme différence 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 cela. L'élément title
est passé à votre fonction. JavaScript si vous ne passez pas un paramètre, la valeur par défaut à une valeur nulle. De plus en JavaScript si votre variable est une valeur nulle, il est considéré comme faux par les opérateurs logiques. Donc, si cette fonction est appelée avec un titre donné, il est une valeur non-fausse et donc affecté à la variable locale. Cependant, si elle ne reçoit pas une valeur, il est une valeur nulle et donc fausse. L'opérateur-or
logique évalue ensuite la seconde expression et de l'erreur "retours à la place. Alors maintenant, la variable locale reçoit la valeur « Erreur ».
Cela fonctionne en raison de la mise en œuvre des expressions logiques en JavaScript. Il ne retourne pas une valeur correcte booléenne (true
ou false
), mais retourne à la place la valeur il a été donné sous certaines règles quant à ce qui est considéré comme équivalent à true
et ce qui est considéré comme équivalent à false
. Recherchez votre référence JavaScript pour savoir ce que JavaScript considère comme vrai ou faux dans des contextes booléens.
Double tuyau signifie logique « OU ». Ce n'est pas vraiment le cas lorsque le paramètre « non défini », puisque strictement le javascript si vous avez du code comme ceci:
function foo(par) {
}
appelle ensuite
foo()
foo("")
foo(null)
foo(undefined)
foo(0)
ne sont pas équivalents.
tuyau double (||) va lancer le premier argument de booléens et si booléen résultant est vrai -. Est-ce l'affectation sinon il attribuera la partie droite
Ce point est important si vous vérifiez pour le paramètre non défini.
Disons que nous avons une setSalary fonction qui a un paramètre optionnel. Si l'utilisateur ne fournit pas le paramètre alors la valeur par défaut de 10 doit être utilisé.
si vous faites le chèque comme ceci:
function setSalary(dollars) {
salary = dollars || 10
}
Cela donnera des résultats inattendus sur appel comme
setSalary(0)
Il conservera tout de même les 10 suivant le flux décrit ci-dessus.
Fondamentalement, il vérifie si la valeur avant la || évalue true, si oui, il prend cette valeur, sinon, il prend la valeur après la ||.
Les valeurs pour lesquelles il prendra la valeur après la || (Pour autant que je me souviens):
- non défini
- false
- 0
- '' (chaîne vide ou nulle)
opérateur à double tuyau
est cet exemple utile?
var section = document.getElementById('special');
if(!section){
section = document.getElementById('main');
}
peut aussi être
var section = document.getElementById('special') || document.getElementById('main');
Alors que La réponse de Cletus est correct, je pense que plus de détails devraient être ajoutés en ce qui concerne « est évalué à faux » en JavaScript.
var title = title || 'Error';
var msg = msg || 'Error on Request';
Il ne s'agit pas seulement de vérifier si le titre/le message a été fourni, mais aussi si l'un ou l'autre l'est. faux.c'est à dire.l'un des éléments suivants :
- FAUX.
- 0 (zéro)
- "" (chaîne vide)
- nul.
- indéfini.
- NaN (une valeur numérique spéciale signifiant Pas un nombre !)
Donc dans la ligne
var title = title || 'Error';
Si le titre est vrai (c'est-à-dire pas faux, donc titre = "titreMessage" etc.), alors l'opérateur booléen OU (||) a trouvé une valeur « vraie », ce qui signifie qu'il est évalué à vrai, donc il court-circuite et renvoie la vraie valeur (titre).
Si le titre est faux (c.-à-d.l'une de la liste ci-dessus), alors l'opérateur booléen OU (||) a trouvé une valeur « fausse » et doit maintenant évaluer l'autre partie de l'opérateur, « Erreur », qui est évaluée comme vraie et est donc renvoyée.
Il semblerait également (après quelques expérimentations rapides sur la console Firebug) que si les deux côtés de l'opérateur sont évalués comme faux, il renvoie le deuxième opérateur « faux ».
c'est à dire.
return ("" || undefined)
renvoie undefined, c'est probablement pour vous permettre d'utiliser le comportement demandé dans cette question lorsque vous essayez de définir le titre/message par défaut sur "".c'est à dire.après avoir couru
var foo = undefined
foo = foo || ""
foo serait défini sur ""
Pour ajouter une explication à tous dit avant moi, je 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 évalué comme une véritable déclaration, il sera terminé et le côté gauche sera retourné et affecté à la variable. dans d'autres cas, le côté droit sera retourné et attribué.
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
Citation: "Qu'est-ce que la construction x = x || y signifie"
Affectation d'une valeur par défaut.
Ce moyen fournir une valeur par défaut de y à x , en cas x est toujours en attente de sa valeur, mais n'a pas encore reçu ou a été délibérément omis afin de revenir à une valeur par défaut.
Et je dois ajouter une chose: Ce bit de raccourci est une abomination. Il abuse d'une optimisation de l'interprète accidentelle (sans prendre la peine avec la deuxième opération si le premier est truthy) pour contrôler une affectation. Cette utilisation n'a rien à voir avec le but de l'opérateur. Je ne crois pas qu'il ne devrait jamais être utilisé.
Je préfère l'opérateur ternaire pour l'initialisation, par exemple,
var title = title?title:'Error';
Il utilise une opération conditionnelle d'une ligne à son but correct. Il joue encore des jeux disgracieux avec truthiness mais, c'est le Javascript pour vous.