Из отчета об ошибке я думаю, что следующее выражение может вызвать исключение, если x равен нулю:

if ( !x || doSomething( x[prop], y[prop] ) === false )

Исключение составляют:

Невозможно прочитать свойство 'prop' из null

... как будто правая сторона || оценивается, даже если левая сторона верна. ссылка на JavaScript указывает на то, что это должно не бывает, но я не уверен. Я проверял, что просто запись x = null не (всегда) приводит к сбою, но гарантируется ли это на каждом движке JS?

РЕДАКТИРОВАТЬ:

Тот же вопрос о

if( x && foo( x[prop] ) === true && bar() === false )

Один из способов сказать это:

Если (a && b && c)

... оценивает b или c, если a === false? В этом случае документ не совсем ясно, только для "a && (expr1 && expr2)", а не для "&& expr1 && expr2"

Полный фрагмент кода

var x = null;
var y = {
  "p1": "p1",
  "p2": "p2"
};

function f() {
  return true;
}

for (var propName in y) {

  if (x && f(y[propName]) === true && f(y[propName]) === false) {
    doSomething(x[propName], y[propName]);
  } else if (!x || f(x[propName], y[propName]) === false) {
    console.log(y[propName]);
  }
}

EDIT2: для полноты, настоящий (свернутый) код, который запускается в браузере

  function a(c, b, e, f) {

        for (var d in b) {
          if (c && _.isObject(b[d]) === true && _.isArray(b[d]) === false) {
            a(c[d], b[d], e, d + ".")
          } else {
            if (!c || _.isEqual(c[d], b[d]) === false) {
              e.push({
                name: f + d,
                value: b[d]
              })
            }
          }
        }
        return e
      }
1
Ilya 18 Дек 2015 в 17:52

3 ответа

Лучший ответ

"Это гарантировано на каждом двигателе JS?"

Мы не можем знать это наверняка, но стандарт определяет, как эти операторы должны быть реализованы.

Логическое ИЛИ:

  1. Пусть lref будет результатом оценки логического выражения .
  2. Пусть lval будет GetValue (lref) .
  3. Если ToBoolean (lval) равен true , верните lval .
  4. Пусть rref будет результатом оценки LogicalANDExpression .
  5. Вернуть GetValue (rref) .

http://es5.github.io/#x11.11

Пункт 3 не оставляет места для сомнений, lval возвращается немедленно, если lref может быть оценен как верный, а rref никогда не будет оцениваться ,

2
Teemu 18 Дек 2015 в 17:07
if (typeof y != 'undefined' && typeof x != 'undefined' && x !== null && y !== null) {
   if (doSomething( x[prop], y[prop] ) === false) {
       //do stuff
   }
}

Сделайте проверку безопасности раньше. это должно работать

Но примечание :

Если ваш prop атрибут не существует, это также вернет ошибку!

Привет

0
messerbill 18 Дек 2015 в 14:58

Оператор Javascript || имеет короткое замыкание. Правая сторона не будет оценивать, если левая сторона true. Это фундаментальное свойство оператора и должно быть одинаково реализовано на всех двигателях.

Поэтому правая часть будет оценивать, только если x равен truey , и все истинные значения в Javascript должны быть подписаны без ошибок.

Сказав это, y совершенно неизвестен в этом примере и может выдать ошибку.

3
deceze 18 Дек 2015 в 14:58