Подтвердить что ты не робот

Как использовать экзистенциальный оператор CoffeeScript для проверки некоторых свойств объекта для undefined?

Я хотел бы использовать экзистенциальный оператор CoffeeScript для проверки некоторых свойств объекта для undefined. Однако я столкнулся с небольшой проблемой.

Код вроде этого:

console.log test if test?

Скомпилируется:

if (typeof test !== "undefined" && test !== null) console.log(test);

Какое поведение я бы хотел видеть. Однако, когда я пытаюсь использовать его против свойств объекта, например:

console.log test.test if test.test?

Я получаю что-то вроде этого:

if (test.test != null) console.log(test.test);

Что не похоже на проверку против undefined вообще. Единственный способ, которым я мог достичь такого же (1:1) поведения, как использование его для объектов, - это сделать большую проверку:

console.log test.test if typeof test.test != "undefined" and test.test != null

Вопрос: я делаю что-то неправильно? Или это скомпилированный код, который достаточно для проверки существования свойства (нулевая проверка с преобразованием типов)?

4b9b3361

Ответ 1

Это общая точка смущения с экзистенциальным оператором: Иногда

x?

компилируется в

typeof test !== "undefined" && test !== null

и в других случаях он просто компилируется в

x != null

Оба эквивалентны, потому что x != null будет false, когда x либо null, либо undefined. Итак, x != null - более компактный способ выражения (x !== undefined && x !== null). Причина компиляции typeof заключается в том, что компилятор считает, что x может вообще не определяться, и в этом случае выполнение теста равенства вызовет ReferenceError: x is not defined.

В вашем конкретном случае test.test может иметь значение undefined, но вы не можете получить ReferenceError, ссылаясь на свойство undefined на существующий объект, поэтому компилятор выбирает более короткий вывод.

Ответ 2

Этот JavaScript:

a.foo != null

действительно проверяет, не является ли свойство foo a ни undefined, ни null. Обратите внимание, что a.foo? переводится на JavaScript, который использует != null, а не !== null. Преобразования, которые != означают, что оба они верны:

null == null
undefined == null

Простой a? становится этим JavaScript:

typeof a !== "undefined" && a !== null

потому что есть три условия для проверки:

  • Есть ли a в области видимости в любом месте?
  • Имеет ли значение a значение undefined?
  • Имеет ли a значение null?

Первое условие важно, так как просто говоря a != null будет запускать ReferenceError, если в области нет a, но typeof a === 'undefined' не будет. Проверка typeof также выполняет условие a === undefined в 2. Затем мы можем завершить его строгим тестом a !== null, поскольку он заботится о 3 без снижения производительности ненужного != (примечание: != и == медленнее, чем !== и === из-за неявных преобразований).

Небольшое чтение о том, что != и !== может быть плодотворным:

MDN: Операторы сравнения


Что касается вашего комментария к удаленному ответу, if(a.foo) является вполне допустимым синтаксисом , если вы заполняете оператор if:

if(a.foo)
    do_interesting_things()
# or
do_interesting_things() if(a.foo)

Однако if(a.foo) и if(a.foo?) отличаются тем, как они обрабатывают 0, false и ''.

Ответ 3

Дикая догадка; вы пробовали console.log test.test if test?.test??

Просто протестируйте его с помощью coffee -p -e 'console.log test.test if test?.test?', который компилируется в:

(function() {

if ((typeof test! == "undefined" && test! == null? test.test: void 0)!= Null) {     console.log(test.test); }

}) вызова (это);.