web-dev-qa-db-fra.com

ReferenceError: membre gauche non valide dans l'affectation

mon code pour un jeu de ciseaux de papier rock (appelé lancer) est comme suit:

var toss = function (one,two) {
    if(one = "rock" && two = "rock") {
        console.log("Tie! Try again!");
    }
    // more similar conditions with `else if`
};

Quand j'entre dans les paramètres

toss("rock","rock")

Je reçois ce code d'erreur:

"ReferenceError: Côté gauche non valide dans l'affectation"

Comment le réparer? Que signifie cette erreur et quels sont les autres cas où cette erreur peut se produire?

24
Kevin

Vous devez utiliser == pour comparer (ou même ===, si vous voulez comparer les types). Un seul = est pour assignation.

if (one == 'rock' && two == 'rock') {
    console.log('Tie! Try again!');
}
47
Joseph Silber

Causes courantes de l'erreur:

  • utilisation de l'affectation (=) au lieu de l'égalité (==/===)
  • assignation au résultat de la fonction foo() = 42 au lieu de passer des arguments (foo(42))
  • simplement des noms de membres manquants (c'est-à-dire en supposant une sélection par défaut): getFoo() = 42 au lieu de getFoo().theAnswer = 42 ou un tableau d'indexation getArray() = 42 au lieu de getArray()[0]= 42

Dans ce cas particulier, vous voulez utiliser == (Ou mieux === - Qu'est-ce que Type Coercion dans Javascript? ) pour vérifier l'égalité (comme if(one === "rock" && two === "rock"), mais la raison pour laquelle vous obtenez l'erreur est plus délicate.

La raison de l'erreur est Priorité de l'opérateur . Nous recherchons en particulier && (Priorité 6) et = (Priorité 3).

Mettons des accolades dans l'expression en fonction de la priorité - && Est supérieur à =, De sorte qu'il est exécuté en premier de la même manière que l'on ferait 3+4*5+6 Comme 3+(4*5)+6:

 if(one= ("rock" && two) = "rock"){...

Nous avons maintenant une expression similaire à plusieurs affectations comme a = b = 42 Qui, en raison de l’associativité de droite à gauche, est exécutée sous la forme a = (b = 42). Donc, en ajoutant plus d'accolades:

 if(one= (  ("rock" && two) = "rock" )  ){...

Enfin, nous sommes arrivés au problème actuel: ("rock" && two) Ne peut pas être évalué à la valeur l pouvant être affectée (dans ce cas particulier, ce sera valeur de two as vérité ).

Notez que si vous utilisiez des accolades pour faire correspondre la priorité perçue entourant chaque "égalité" entre accolades, vous n'obtiendrez aucune erreur. Évidemment, cela produit également un résultat différent de celui auquel vous vous attendiez - modifie la valeur des deux variables et que && Sur deux chaînes "rock" && "rock" Donnant lieu à "rock" (Ce qui est à vrai dire vérité) tout le temps en raison du comportement de logial && :

if((one = "rock") && (two = "rock"))
{
   // always executed, both one and two are set to "rock"
   ...
}

Pour plus de détails sur l'erreur et les autres cas où cela peut arriver - voir spécification:

Affectation

LeftHandSideExpression = AssignmentExpression
...
Lancez une exception SyntaxError si les conditions suivantes sont toutes remplies:
...
IsStrictReference (lref) est vrai

expressions du côté gauche

et type de spécification de référence expliquant IsStrictReference:

... les appels de fonction sont autorisés à renvoyer des références. Cette possibilité est admise uniquement à des fins d'objets Host. Aucune fonction ECMAScript intégrée définie par cette spécification ne renvoie une référence et aucune fonction permettant à une fonction définie par l'utilisateur de renvoyer une référence ...

5
Alexei Levenkov