How does CoffeeScript's existential operator work?

a 夏天 提交于 2019-11-26 07:45:03

问题


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?


回答1:


The documentation says this about ?:

CoffeeScript's existential operator ? returns true unless a variable is null or undefined, which makes it analogous to Ruby's nil?

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.



来源:https://stackoverflow.com/questions/17253772/how-does-coffeescripts-existential-operator-work

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