Pourquoi ces opérateurs logiques renvoient-ils un objet et non un booléen?
var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );
var _ = obj && obj._;
Je veux comprendre pourquoi il retourne le résultat de obj.fn()
(s'il est défini) OR obj._
Mais pas un résultat booléen.
var _ = ((obj.fn && obj.fn() ) || obj._ || ( obj._ == {/* something */}))? true: false
retournera booléen.
MISE À JOUR
Notez que cela est basé sur mes tests. Je ne dois pas me fier entièrement à moi.
C'est une expression qui pas attribue une valeur true
ou false
. Il attribue plutôt la valeur calculée.
Jetons un œil à cette expression.
Un exemple d'expression:
var a = 1 || 2;
// a = 1
// it's because a will take the value (which is not null) from left
var a = 0 || 2;
// so for this a=2; //its because the closest is 2 (which is not null)
var a = 0 || 2 || 1; //here also a = 2;
Votre expression:
var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );
// _ = closest of the expression which is not null
// in your case it must be (obj.fn && obj.fn())
// so you are gettig this
Une autre expression:
var a = 1 && 2;
// a = 2
var a = 1 && 2 && 3;
// a = 3 //for && operator it will take the fartest value
// as long as every expression is true
var a = 0 && 2 && 3;
// a = 0
Une autre expression:
var _ = obj && obj._;
// _ = obj._
En JavaScript, les deux ||
et &&
sont des opérateurs de court-circuit logiques qui renvoient la première "valeur logique" entièrement déterminée lorsqu'ils sont évalués de gauche à droite.
Dans l'expression X || Y
, X
est d'abord évalué et interprété comme une valeur booléenne. Si cette valeur booléenne est "true", elle est renvoyée. Et Y
n'est pas évalué. (Parce que peu importe si Y
est vrai ou Y
est faux, X || Y
a été entièrement déterminé.) C'est la partie de court-circuit.
Si cette valeur booléenne est "false", nous ne savons toujours pas si X || Y
est vrai ou faux jusqu'à ce que nous évaluions Y
et que nous l'interprétions également comme une valeur booléenne. Ainsi, Y
est renvoyé.
Et &&
fait de même, sauf qu'il arrête d'évaluer si le premier argument est faux.
La première partie délicate est que lorsqu'une expression est évaluée comme "vraie", alors l'expression elle-même est renvoyée. Ce qui compte comme "vrai" dans les expressions logiques, mais vous pouvez également l'utiliser. C'est pourquoi vous voyez des valeurs réelles renvoyées.
La deuxième partie délicate est que lorsqu'une expression est évaluée comme "fausse", alors dans JS 1.0 et 1.1, le système renvoie une valeur booléenne de "faux"; tandis que dans JS 1.2, il retourne la valeur réelle de l'expression.
Dans JS false
, 0
, -0
, ""
, null
, undefined
, NaN
et document.all
tout compte comme faux .
Ici, je cite bien sûr des valeurs logiques pour la discussion. Bien sûr, la chaîne littérale "false"
n'est pas identique à la valeur false
, et est donc vrai.
En termes simples:
Le ||
L'opérateur renvoie la première valeur véridique, et si aucune n'est véridique, il renvoie la dernière valeur (qui est une valeur fausse).
Le &&
L'opérateur renvoie la première valeur falsifiée, et si aucune n'est fausse, il renvoie la dernière valeur (qui est une valeur véridique).
C'est vraiment aussi simple que cela. Expérimentez dans votre console pour voir par vous-même.
"" && "Dog" // ""
"Cat" && "Dog" // "Dog"
"" || "Dog" // "Dog"
"Cat" || "Dog" // "Cat"
Je pense que vous avez une question de méthodologie JavaScript de base ici.
Maintenant, JavaScript est un langage peu typé. En tant que tel, la manière et la manière dont il traite les opérations logiques diffère de celles d'autres langages standard comme Java et C++. JavaScript utilise un concept appelé "type coercition" pour déterminer la valeur d'un opération logique et renvoie toujours la valeur du premier type true
. Par exemple, jetez un œil au code ci-dessous:
var x = mystuff || document;
// after execution of the line above, x = document
En effet, mystuff
est une entité a priori non définie qui sera toujours évaluée à false
lorsqu'elle est testée et en tant que telle, JavaScript ignore cela et teste l'entité suivante pour un true
valeur. Étant donné que l'objet document est connu de JavaScript, il renvoie une valeur true
et JavaScript renvoie cet objet.
Si vous souhaitez qu'une valeur booléenne vous soit retournée, vous devrez passer votre instruction de condition logique à une fonction comme ceci:
var condition1 = mystuff || document;
function returnBool(cond){
if(typeof(cond) != 'boolean'){ //the condition type will return 'object' in this case
return new Boolean(cond).valueOf();
}else{ return; }
}
// Then we test...
var condition2 = returnBool(condition1);
window.console.log(typeof(condition2)); // outputs 'boolean'
On peut se référer ici à la spécification (11.11) de JS:
Sémantique
L'expression LogicalANDExpression de production: LogicalANDExpression && BitwiseORExpression est évaluée comme suit:
2.Appelez GetValue (Résultat (1)).
3.Appelez ToBoolean (Résultat (2)).
4.Si le résultat (3) est faux, renvoyez le résultat (2).
5.Évaluez BitwiseORExpression.
6.Appelez GetValue (Résultat (5)).
Résultat de retour (6).
voir ici pour la spécification
Dans la plupart des langages de programmation, les opérateurs &&
Et ||
Renvoient un booléen. En JavaScript c'est différent.
OU opérateur:
Il renvoie la valeur du premier opérande qui valide comme vrai (le cas échéant), sinon il renvoie la valeur du dernier opérande ( même s'il est validé comme faux) .
Exemple 1:
var a = 0 || 1 || 2 || 3;
^ ^ ^ ^
f t t t
^
first operand that validates as true
so, a = 1
Exemple 2:
var a = 0 || false || null || '';
^ ^ ^ ^
f f f f
^
no operand validates as true,
so, a = ''
ET opérateur:
Il retourne la valeur du dernier opérande qui valide comme vrai (si toutes les conditions valident comme vrai), sinon il retourne la valeur du premier opérande qui valide comme faux .
Exemple 1:
var a = 1 && 2 && 3 && 4;
^ ^ ^ ^
t t t t
^
last operand that validates as true
so, a = 4
Exemple 2:
var a = 2 && '' && 3 && null;
^ ^ ^ ^
t f t f
^
entire condition is false, so return first operand that validates as false,
so, a = ''
Conclusion:
Si vous voulez que JavaScript agisse de la même manière que les autres langages de programmation, utilisez la fonction Boolean()
, comme ceci:
var a = Boolean(1 || 2 || 3);// a = true
Tout d'abord, il doit être vrai pour revenir, donc si vous testez la véracité, cela ne fait aucune différence
Deuxièmement, il vous permet de faire des affectations selon:
function bar(foo) {
foo = foo || "default value";
Comparer:
var prop;
if (obj.value) {prop=obj.value;}
else prop=0;
avec:
var prop=obj.value||0;
Renvoyer une expression véridique - plutôt que juste ou fausse - rend généralement votre code plus court et toujours lisible. C'est très courant pour ||, pas tant pour &&.
Vous devriez considérer les opérateurs de court-circuit comme conditionnels plus que les opérateurs logiques.
x || y
correspond grosso modo à:
if (x) { return x } else { return y; }
et x && y
correspond grosso modo à:
if (x) { return y } else { return x; }
Compte tenu de cela, le résultat est parfaitement compréhensible.