问题 CoffeeScript Existential Operator和这个


我注意到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

4576
2018-04-03 11:48


起源

可能重复 存在的运算符和对象属性 - mu is too short


答案:


如果是:

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  - 只是 != 足够

14
2018-04-03 12:07



我明白那个。我的问题更多地与检查对象上的属性的存在有关.. this.var,或者.var.property ..等等。它省略了未定义的检查,只做了!= null而不是!== null .. 。 - Jason L.
我现在知道了。我不得不把这归结为我对CoffeeScript编译器缺乏了解:)我真的不知道它是否足够智能来做出这些“决定”。不过,这真的很好。非常感谢您的见解! - Jason L.