Ответ 1
Вы должны использовать ==
для сравнения (или даже ===
, если вы хотите сравнить типы). Единственный =
предназначен для назначения.
if (one == 'rock' && two == 'rock') {
console.log('Tie! Try again!');
}
мой код для игры с ножницами из каменной бумаги (под названием toss) выглядит следующим образом:
var toss = function (one,two) {
if(one = "rock" && two = "rock") {
console.log("Tie! Try again!");
}
// more similar conditions with `else if`
};
Когда я вхожу в параметры
toss("rock","rock")
Я получаю этот код ошибки:
"ReferenceError: Недопустимая левая сторона в назначении"
Как это исправить? Что означает эта ошибка и какие другие случаи, когда эта ошибка может произойти?
Вы должны использовать ==
для сравнения (или даже ===
, если вы хотите сравнить типы). Единственный =
предназначен для назначения.
if (one == 'rock' && two == 'rock') {
console.log('Tie! Try again!');
}
Общие причины ошибки:
=
) вместо равенства (==
/===
)foo() = 42
вместо передачи аргументов (foo(42)
)getFoo() = 42
вместо getFoo().theAnswer = 42
или индексации массива getArray() = 42
вместо getArray()[0]= 42
В этом конкретном случае вы хотите использовать ==
(или лучше ===
- Что такое Type Coercion в Javascript?), чтобы проверить равенство (например, if(one === "rock" && two === "rock")
, но фактическая причина, по которой вы получаете ошибку, сложнее.
Причиной ошибки является приоритет оператора. В частности, мы ищем &&
(приоритет 6) и =
(приоритет 3).
Положим фигурные скобки в выражении в соответствии с приоритетом - &&
выше, чем =
, поэтому он выполняется сперва аналогично тому, как можно было бы сделать 3+4*5+6
как 3+(4*5)+6
:
if(one= ("rock" && two) = "rock"){...
Теперь мы имеем выражение, подобное множеству присваиваний типа a = b = 42
, которое из-за ассоциативности справа налево выполняется как a = (b = 42)
. Поэтому добавление большего количества фигурных скобок:
if(one= ( ("rock" && two) = "rock" ) ){...
Наконец, мы пришли к реальной проблеме: ("rock" && two)
не может быть оценен как l-значение, которое может быть присвоено (в этом конкретном случае это будет значение two
как truthy).
Обратите внимание: если вы будете использовать фигурные скобки для соответствия воспринимаемому приоритету, окружающему каждое "равенство" с помощью фигурных скобок, вы не получите ошибок. Очевидно, что это также приводит к другому результату, чем вы ожидали, - изменяет значение обеих переменных, а не &&
на две строки "rock" && "rock"
, что приводит к тому, что "rock"
(что в свою очередь является правдивым) все время из-за поведения логический &&:
if((one = "rock") && (two = "rock"))
{
// always executed, both one and two are set to "rock"
...
}
Более подробную информацию об ошибке и других случаях, когда это может произойти, см. в спецификации:
LeftHandSideExpression = AssignmentExpression
...
Выбросить исключение SyntaxError, если выполняются следующие условия:
...
IsStrictReference (lref) истинно
и Тип ссылочной спецификации, объясняющий IsStrictReference:
... вызовам функций разрешено возвращать ссылки. Эта возможность допускается исключительно ради объектов-хозяев. Никакая встроенная функция ECMAScript, определенная этой спецификацией, не возвращает ссылку, и нет никакой возможности для пользовательской функции вернуть ссылку...