CoffeeScript Existential Operator和这个

时间:2012-04-03 11:48:39

标签: 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 个答案:

答案 0 :(得分:14)

以下情况:

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!=会将其转换为null。这就是我们不需要额外检查的原因 简而言之:

  • 访问未定义的变量会引发异常 - 需要检查typeof
  • 访问未定义的属性返回undefined - 只需!=就足够了