如何使用CoffeeScript存在运算符检查未定义的某些对象属性?

时间:2012-04-03 09:01:02

标签: coffeescript existential-operator

我想使用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);

哪个看起来不像是对未定义的检查。我可以实现与使用对象相同(1:1)行为的唯一方法是使用更大的检查:

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

问题是 - 我做错了吗?或者编译后的代码是否足以检查是否存在属性(带有类型转换的空检查)?

3 个答案:

答案 0 :(得分:50)

这是与存在主体运算符混淆的常见点:有时候

x?

编译到

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

有时它只是编译成

x != null

两者是等效的,因为x != null falsexnullundefinedx != null。因此,(x !== undefined && x !== null)是一种表达typeof的更紧凑的方式。 x编译发生的原因是编译器认为ReferenceError: x is not defined可能根本没有定义,在这种情况下,进行相等性测试会触发test.test

在您的特定情况下,undefined可能具有值ReferenceError,但您无法通过引用现有对象上的未定义属性来获取{{1}},因此编译器选择较短的输出。

答案 1 :(得分:20)

这个JavaScript:

a.foo != null

实际上会检查foo的{​​{1}}属性是a还是undefined。请注意,null已转换为使用a.foo?而不是!= null的JavaScript。 !== null所做的转换意味着这两者都是正确的:

!=

普通null == null undefined == null 成为这个JavaScript:

a?

因为有三个条件需要检查:

  1. 范围内是否有typeof a !== "undefined" && a !== null
  2. a的值是否为a
  3. undefined的值是否为a
  4. 第一个条件非常重要,因为如果范围中没有null但是a != null不会,a会触发ReferenceError。 typeof a === 'undefined'检查还会处理 2 中的typeof条件。然后我们可以通过严格的a === undefined测试来完成它,因为它可以处理 3 而不会对不必要的a !== null造成性能损失(注意:!=和{由于隐式转换,{1}}慢于!===

    关于!=====做什么可​​能会有所收获:

      

    MDN: Comparison Operators


    就您对已删除答案的评论而言,!=是完全有效的语法如果您完成!==语句:

    if(a.foo)

    但是,ifif(a.foo) do_interesting_things() # or do_interesting_things() if(a.foo) 处理if(a.foo)if(a.foo?)0的方式不同。

答案 2 :(得分:4)

疯狂猜测;你试过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); }

     

})调用(这);