Недопустимое левое присваивание, проверка переменной и установка другой в операторе IF

if(a=="check" && b=some())

Оператор if (теоретически) вернет true, если a равно "check" и если some() вернет нечто, отличное от false/0/null/undefined.

Но это выдает ошибку: ReferenceError: Недопустимая левая часть присваивания.

В контексте:

function some(){
  return (window.title=="Special")? 0 : window.title;
}
function check(a){
   var b;
   if(a == 1 && b = some()){
      alert("Window's title is: "+b);
   }
}

Как я могу сделать это без использования двух операторов if? Является ли это возможным?


person JCOC611    schedule 13.02.2011    source источник


Ответы (1)


Сгруппируйте его с ().

if( a=="check" && ( b=some() ) )

http://jsfiddle.net/KsWBq/

Это оценит выражение присваивания, затем результат этого выражения будет использоваться оператором if().

person user113716    schedule 13.02.2011
comment
Не могу поверить, что это так просто. Спасибо! - person JCOC611; 13.02.2011
comment
Мне нужно подождать 10 минут, чтобы принять ответ, так что наберитесь терпения :) - person JCOC611; 13.02.2011
comment
@alex: Честно говоря, я не смогу дать подробный ответ о том, как именно это видит интерпретатор, но мое неуклюжее объяснение состоит в том, что () позволяет ему завершить выражение присваивания и оценить результат. Возможно, без () он оценивает b, а затем находит =some(), болтающийся там один. - person user113716; 13.02.2011
comment
Если вы проверяете одну переменную, браузер ожидает, что вы проверите другую. Поэтому, если вы оцениваете только if(b = some()), нет необходимости в дополнительных () - person JCOC611; 13.02.2011
comment
@ JCOC611: Да, я вижу, что это также работает, если вы делаете if( a=="check" && b,b = some() ) {, поэтому я думаю, что именно здесь он эффективно разбивал выражение присваивания, оценивая b, а затем переходя к = some(). jsfiddle.net/KsWBq/2 - person user113716; 13.02.2011
comment
Все дело в приоритете операций в языке. Операторы связаны более или менее жестко; * связывает сильнее, чем, например, +. Оператор присваивания находится довольно низко в списке приоритетов, и, в частности, && связывает более тесно, чем =. Вот — хорошая диаграмма приоритета операторов JavaScript. (Обратите внимание, что , является последним, что объясняет, почему последняя пара комментариев.) - person Pointy; 13.02.2011
comment
Спасибо @Pointy. Имеет смысл. Итак, поскольку , является последним, b = some() оценивается перед b? Это немного сбивает с толку, поскольку в нем говорится, что , идет слева направо. Я предполагал, что он оценивает b, а затем b = some(), который в конечном итоге использовался для оценки. - person user113716; 13.02.2011
comment
...не берите в голову. Я вижу в тесте, что он, кажется, идет слева направо. - person user113716; 13.02.2011