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

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

Code like this:

console.log test if test? 

The following will compile:

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

What kind of behavior I would like to see. However, when I try to use it against the properties of an object, for example:

 console.log test.test if test.test? 

I get something like this:

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

Which is not like checking against undefined at all. The only way I could achieve the same (1: 1) behavior as using it for objects is to do a big check:

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

Question: Am I doing something wrong? Or is it compiled code that is enough to check for the existence of a property (null checking with type conversion)?

+22
coffeescript
Apr 03 2018-12-12T00:
source share
3 answers

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

 x? 

compiles to

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

and in other cases it just compiles to

 x != null 

Both are equivalent because x != null will be false when x either null or undefined . So x != null is a more compact way of expressing (x !== undefined && x !== null) . The reason for compiling typeof is because the compiler believes that x may not be defined at all, in which case running an equality test will raise ReferenceError: x is not defined .

In your specific case, test.test may be undefined , but you cannot get a ReferenceError by referring to the undefined property of an existing object, so the compiler chooses a shorter output.

+45
Apr 03 2018-12-12T00:
source share
— -

This javascript:

 a.foo != null 

really checks if the foo a property is neither undefined nor null . Please note that a.foo? translates to JavaScript that uses != null , not !== null . Transformations that != Mean they are both true:

 null == null undefined == null 

Simple a? becomes this javascript:

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

because there are three conditions to check:

  • Is there a in scope anywhere?
  • Does a have a value of undefined ?
  • Is a a null ?

The first condition is important, because simply saying a != null will throw a ReferenceError if there is no a in the area, but typeof a === 'undefined' will not. The typeof check also fulfills the condition a === undefined in 2 . Then we can end it with a rigorous test a !== null , since it takes care of 3 without sacrificing unnecessary performance != (Note != And == slower than !== and === due to implicit conversions).

A little reading about what != And !== can be fruitful:

MDN: Comparison Operators




As for your comment on the remote answer, if(a.foo) is perfectly valid syntax if you populate the if :

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

+20
Nov 15 '13 at 21:02
source share

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

Just test 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) ;.

+4
Apr 03 '12 at 10:40
source share



All Articles