How do I use the CoffeeScript existential operator to check some object properties for undefined?

前端 未结 3 1857
面向向阳花
面向向阳花 2020-12-02 15:56

I would like to use the CoffeeScript existential operator to check some object properties for undefined. However, I encountered a little problem.

Code like this:

相关标签:
3条回答
  • 2020-12-02 16:21

    Wild guess; have you tried console.log test.test if test?.test??

    Just tested it with coffee -p -e 'console.log test.test if test?.test?', which compiles to:

    (function() {

    if ((typeof test !== "undefined" && test !== null ? test.test : void 0) != null) { console.log(test.test); }

    }).call(this);

    0 讨论(0)
  • 2020-12-02 16:27

    This is a common point of confusion with the existential operator: Sometimes

    x?
    

    compiles to

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

    and other times it just compiles to

    x != null
    

    The two are equivalent, because x != null will be false when x is either null or undefined. So x != null is a more compact way of expressing (x !== undefined && x !== null). The reason the typeof compilation occurs is that the compiler thinks x may not have been defined at all, in which case doing an equality test would trigger ReferenceError: x is not defined.

    In your particular case, test.test may have the value undefined, but you can't get a ReferenceError by referring to an undefined property on an existing object, so the compiler opts for the shorter output.

    0 讨论(0)
  • 2020-12-02 16:27

    This JavaScript:

    a.foo != null
    

    actually does check if the foo property of a is neither undefined nor null. Note that a.foo? is translated to JavaScript that uses != null rather than !== null. The conversions that != does means that both of these are true:

    null == null
    undefined == null
    

    A plain a? becomes this JavaScript:

    typeof a !== "undefined" && a !== null
    

    because there are three conditions to check:

    1. Is there an a in scope anywhere?
    2. Does a have a value of undefined?
    3. Does a have a value of null?

    The first condition is important as just saying a != null will trigger a ReferenceError if there is no a in scope but saying typeof a === 'undefined' won't. The typeof check also takes care of the a === undefined condition in 2. Then we can finish it off with a strict a !== null test as that takes care of 3 without the performance penalty of an unnecessary != (note: != and == are slower than !== and === due to the implicit conversions).

    A little reading on what != and !== do might be fruitful:

    MDN: Comparison Operators


    As far as your comment on the deleted answer is concerned, if(a.foo) is perfectly valid syntax if you complete the if statement:

    if(a.foo)
        do_interesting_things()
    # or
    do_interesting_things() if(a.foo)
    

    However, if(a.foo) and if(a.foo?) differ in how they handle 0, false, and ''.

    0 讨论(0)
提交回复
热议问题