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

我是研究僧i 提交于 2019-12-01 14:11:08

问题


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:

console.log test if test?

Compiles to:

if (typeof test !== "undefined" && test !== null) console.log(test);

Which is the behavior I would like to see. However, when I try using it against object properties, like this:

console.log test.test if test.test?

I get something like that:

if (test.test != null) console.log(test.test);

Which desn't look like a check against undefined at all. The only way I could have achieved the same (1:1) behavior as using it for objects was by using a larger check:

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

The question is - am I doing something wrong? Or is the compiled code what is enough to check for existence of a property (a null check with type conversion)?


回答1:


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.




回答2:


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 ''.




回答3:


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);



来源:https://stackoverflow.com/questions/20010245/coffeescript-not-null-or-undefined-behavior

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!