2013-09-03 14 views
11

mój kod na nożyczki papier rock gry (zwane Toss) przedstawia się następująco:ReferenceError: Nieprawidłowa lewa w przypisania

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

Kiedy wchodzę w parametrach

toss("rock","rock") 

otrzymuję ten kod błędu:

"ReferenceError: Invalid left-hand side in assignment"

Jak to naprawić? Co ten błąd oznacza i jakie inne przypadki, kiedy ten błąd może się zdarzyć?

+0

Trzy "związać" przypadki mogą być uproszczone do pojedynczego 'if (jeden == dwa)' –

Odpowiedz

35

Musisz użyć ==, aby porównać (lub nawet ===, jeśli chcesz porównać typy). Pojedynczy = służy do przypisania.

if (one == 'rock' && two == 'rock') { 
    console.log('Tie! Try again!'); 
} 
+3

jestem dureń .... ....dzięki! – Kevin

+0

dla wyjaśnienia, jaka byłaby różnica między == a ===? – Kevin

+0

Powyższy komentarz jest nieco błędny, ECMA określa, że ​​nie jest to kontrola typu, wykonuje operację zwaną typem przymusu. Jest to naprawdę przydatne, aby wiedzieć, zobacz tę odpowiedź http://stackoverflow.com/questions/19915688/what-exactly-is-type-coercion-in-javascript – VladNeacsu

1

Najczęstsze przyczyny błędu:

  • wykorzystanie przydziału (=) zamiast równości (==/===)
  • przypisanie spowoduje funkcji foo() = 42 zamiast argumentów przechodzących (foo(42))
  • po prostu brakuje nazw członków (tj. Przy założeniu, że wybrano domyślny wybór): getFoo() = 42 zamiast getFoo().theAnswer = 42 lub indeksu tablicy ing getArray() = 42 zamiast getArray()[0]= 42

W tym konkretnym przypadku, którego chcesz użyć == (lub lepiej === - What exactly is Type Coercion in Javascript?) w celu sprawdzenia równości (jak if(one === "rock" && two === "rock"), ale rzeczywista przyczyna otrzymujesz błąd jest trudniejsze.

Powód błędu to Operator precedence. W szczególności szukamy && (pierwszeństwo 6) i = (pierwszeństwo 3).

Postawmy nawiasy w wyrażeniu według priorytetu - && jest wyższa niż = więc jest wykonywany pierwszy podobny sposób można by zrobić 3+4*5+6 jak 3+(4*5)+6:

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

Teraz mamy wyraz podobny do wielu zadań, takich jak a = b = 42 które ze względu na skojarzenie z prawem do lewej wykonane jako a = (b = 42). Więc dodanie większej szelki:

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

Wreszcie dotarliśmy do rzeczywistego problemu: ("rock" && two) nie może być oceniana na l-wartości, które mogą być przypisane do (w tym konkretnym przypadku będzie to wartość z two jak truthy) .

Należy pamiętać, że jeśli użyjesz nawiasów klamrowych, aby dopasować postrzegany priorytet otaczający każdą "równość" za pomocą nawiasów klamrowych, nie otrzymasz żadnych błędów.Oczywiście, że produkuje również inny wynik, niż można by oczekiwać - zmienia wartość obu zmiennych i niż robić && na dwóch ciągów "rock" && "rock" powodując "rock" (co z kolei jest truthy) cały czas ze względu na zachowanie logial &&:

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

uzyskać jeszcze więcej informacji na temat tego błędu i innych przypadkach może się zdarzyć - patrz specyfikacja:

Assignment

LeftHandSideExpression = AssignmentExpression
...
Throw a SyntaxError exception if the following conditions are all true:
...
IsStrictReference(lref) is true

Left-Hand-Side Expressions

i The Reference Specification Type wyjaśniając IsStrictReference:

... function calls are permitted to return references. This possibility is admitted purely for the sake of host objects. No built-in ECMAScript function defined by this specification returns a reference and there is no provision for a user-defined function to return a reference...

Powiązane problemy