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

Экзистенциальный оператор CoffeeScript и этот

Я заметил кое-что немного странное с компилятором CoffeeScript и задавался вопросом, было ли это правильным поведением или нет. Если это правильно, мне любопытно, почему есть разница.

Учитывая следующий код CoffeeScript:

if @myVar?
  alert myVar

Я ожидал, что он будет скомпилирован для JavaScript следующим образом:

if (typeof this.myVar !== "undefined" && this.myVar !== null) {
  alert(myVar);
}

Но вместо этого вывод компилятора CoffeeScript выглядит следующим образом:

if (this.myVar != null) {
  alert(myVar);
}

Если я не ссылаюсь на этот (или любой другой родительский объект), компилятор CoffeeScript компилируется так, как я ожидал.

Это правильное поведение? Если да, то почему он работает при использовании этого?

Изменить:

Чтобы добавить немного больше разъяснений. Это происходит не только с этим, но и с любыми другими свойствами объектов. Например, если бы я заменил вышеприведенный CoffeeScript тем, что ниже, он все же будет компилироваться только с "!= Null"...

if myVar.myProp?
  alert myVar
4b9b3361

Ответ 1

В случае:

myVar = 10
if myVar?
  alert myVar

Компилятор Coffeescript может видеть, что myVar действительно определен в первой строке, поэтому он может опустить проверку typeof myVar !== "undefined".

if (myVar !== null) {
  alert(myVar);
}

Но в этом случае:

if myVar?
  alert myVar
Компилятор

не может гарантировать, что myVar действительно определен, поэтому требуется дополнительная проверка:

if (typeof myVar !== "undefined" && myVar !== null) {
  alert(myVar);
}

Итак, ответ: компилятор Coffeescript пытается быть умным для создания эффективного кода.

ИЗМЕНИТЬ Способ Coffeescript также относится к свойствам: this.prop возвращает undefined, если свойство не определено. != преобразует его в нуль. Вот почему нам не нужна дополнительная проверка.
В нескольких словах:

  • доступ к undefined исключению переменной throw - необходимо проверить typeof
  • доступ к undefined возвращает свойства undefined - просто != достаточно