1

Without @

alert("Even Number") if even?

Corresponding Javascript

if (typeof even !== "undefined" && even !== null) {
  alert("Even Number");
}

With @

alert("Even Number") if @even?

Corresponding Javascript

if (this.even != null) {
  alert("Even Number");
}

I want the check for undefined when I use the this operator along with ? Am I missing something?

Mudassir Ali
  • 7,913
  • 4
  • 32
  • 60

2 Answers2

4

Coffeecript is just being smart. The trick here is that comparing to null with != checks for undefined as well. You don't need to check for existence of the variable because this is already an object, and you can check if a property exists by just using a regular lookup like if (this.prop), but that would fail if the value is falsy (false, empty string, etc...), that's why you need the check for undefined or null which would be written like:

if (this.prop !== undefined && this.prop !== null)

But taking advantage of type casting we can use != to simplify:

if (this.prop != null) // checks null and undefined

Because null == undefined but null !== undefined.

elclanrs
  • 92,861
  • 21
  • 134
  • 171
3

If you refer to an undefined variable, JS throws a ReferenceError. If you refer to an undefined object member, you get undefined. That is why you don't need to check if the object member exists before testing it against null.

Consider:

var obj = {};

if( obj.foo != null ) {   // this is fine because `obj.foo` is `undefined`
   // ...
}

if( foo != null ) {       // ReferenceError, script execution halts
   // ...
}

In other words there is no need to safeguard against the object member not existing so CoffeeScript doesn't do it. You have to do it manually if you want to specifically check for the member not existing at all.

JJJ
  • 32,902
  • 20
  • 89
  • 102
  • a = {test: (-> @b?)} ; a.test() would return false while I want it to return true, I can do manual check to undefined in coffeescript but that is what the "?" is supposed to do which it is failing – Mudassir Ali May 30 '13 at 07:21
  • But in that case you're testing for "truthy or undefined". It's clearly a special case. I'm not really sure what your point is: `a = {test: (-> b?)} ; a.test()` would also return false. – JJJ May 30 '13 at 07:25