Coffeescript uses the existential operator to determine when a variable exists, and in the coffeescript documentation it shows that something?
would compile to something !== undefined && something !== null
however I noticed that my version of coffeescript was only compiling this to something !== null
so I wrote a test to see how this would effect my code
taco = undefined
if taco?
console.log "fiesta!"
else
console.log "No taco!"
which compiled to
// Generated by CoffeeScript 1.4.0
(function() {
var taco;
taco = void 0;
if (taco != null) {
console.log("fiesta!");
} else {
console.log("No taco!");
}
}).call(this);
and outputted the somewhat unexpected No taco!
so my question is two fold. Why does coffeescript no longer check for the value being undefined
and why is this suficiant?
The documentation says this about ?
:
CoffeeScript's existential operator
?
returns true unless a variable is null or undefined, which makes it analogous to Ruby'snil?
so of course this will say "No taco!":
taco = undefined
if taco?
console.log "fiesta!"
else
console.log "No taco!"
Your taco
is explicitly undefined
so taco?
is false.
CoffeeScript implicitly declares variables so the JavaScript form of ?
is context dependent. For example, if you just say only this:
if taco?
console.log "fiesta!"
else
console.log "No taco!"
you'll see that taco?
becomes typeof taco !== "undefined" && taco !== null
. You still see the "is it null
" check (in a tighter form) but there's also the "is there a var taco
" check with typeof
; note that the typeof taco
test also checks for taco = undefined
so a stricter !==
test can be used to see if taco
is null
.
You say this:
I noticed that my version of coffeescript was only compiling this to
something !== null
but that's not what it is doing, it is actually compiling to something != null
; note the use of "sloppy" type converting inequality (!=
) versus the strict inequality (!==
) that you claim is there. The difference between !=
and !==
is important here since:
- Null and Undefined Types are
==
(but not===
)
So if you know that variable v
has been declared (i.e. there is var v
somewhere) then v != null
is sufficient to check that v
is neither null
nor undefined
. However, if you do not know that v
has been declared, then you need a typeof
check to avoid a ReferenceError when you try to compare an undeclared variable with null
. Consider this JavaScript:
if(taco != null) {
console.log("fiesta!");
} else {
console.log("No taco!");
}
That will throw a ReferenceError in your face since taco
does not exist. This:
if(typeof taco !== "undefined" && taco !== null)
console.log("fiesta!");
} else {
console.log("No taco!");
}
on the other hand is fine since the typeof
check guards against trying to access something that hasn't been declared. I don't think you can construct the first one in CoffeeScript without embedding JavaScript using backticks.