web-dev-qa-db-fra.com

Pourquoi les opérateurs logiques (&& et ||) ne renvoient-ils pas toujours un résultat booléen?

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.

48
theateist
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._
17
Santosh Linkha

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.

66
DragonLord

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"
55
Sam Eaton

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' 
3
Ifeora Okechukwu

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:

  1. Évaluez LogicalANDExpression.

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

2
IcyBrk

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
2
evilReiko

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";
1
Quentin

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 &&.

1
Christophe

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.

0
JacquesB