Экзистенциальный оператор 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
Ответы
Ответ 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
- просто !=
достаточно