ab <0, почему это не выдает ошибку, когда ab === undefined? - PullRequest
0 голосов
/ 30 октября 2019

Опечатка завершилась как

a.b > 0

с a.b неопределенным. Согласно MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_operator) сравнение вызывает .valueOf() для операндов. Таким образом, это должно быть

a.b.valueOf() > 0

, но это фактически выдает ошибку, которая, кажется, не происходит. Вместо этого, кажется,оцениваться:

undefined > 0

Я что-то неправильно понимаю?

В моем случае это привело к тихой ошибке в коде Node.js. Я определенно хотел, чтобы вместо этого была выдана ошибка.

Могу ли я справиться с этим без явной проверки операндов?


РЕДАКТИРОВАТЬ: freeCodeCamp, кажется, описывает это более правильно, чем MDN:

https://guide.freecodecamp.org/javascript/comparison-operators/

Но я все еще задаюсь вопросом о самом простом способе справиться с этим, не попав в ловушку простых опечаток.

1 Ответ

2 голосов
/ 30 октября 2019

См. спецификацию : что он делает является :

Пусть r будет результатом выполнения абстрактного реляционного сравнения lval

, которое делает , которое пытается привести каждую сторону к первому примитиву:

а. Пусть px будет? ToPrimitive (x, номер подсказки).

b. Позволяет ли py быть? ToPrimitive (y, номер подсказки).

undefined уже примитив - ничего не выбрасывает. Затем он делает:

Пусть nx будет? ToNumeric (px).

Пусть будет ny? ToNumeric (py).

Приведение undefined к числу также не выбрасывает, но возвращает NaN:

console.log(Number(undefined));

Итак, мы получаем

Если Type (nx) совпадает с Type (ny), вернуть Type (nx) ::lessThan (nx, ny).

, где nx равно NaN и ny равно 0. lessThan возвращает undefined, когда nx равно NaN, описано здесь :

  1. Если x равен NaN, вернуть неопределенное значение.

А затем вернуться к шагу после 5. в самом начале ответа:

Если r не определено, вернуть false. В противном случае верните r.

Результат равен undefined, поэтому возвращается false (без выдачи ошибки).


Таким образом, это должно быть

  a.b.valueOf() > 0

Только объект будет вызывать valueOf в процессе оценки <a. Let px be ? ToPrimitive(x, hint Number). выше). undefined не является объектом - это уже примитив, поэтому на этом шаге не происходит никакого дополнительного преобразования.

Я определенно хотел, чтобы вместо этого была выдана ошибка.

Можно ли обработатьэто без явной проверки операндов?

Не совсем, но это совсем не сложно, просто убедитесь, что a.b - это сначала число, если вы не уверены. if (typeof a.b === 'number'). В этом нет ничего плохого.

...