Thursday, July 28, 2011

CoffeeScript global variable and @ keyword

I finally managed to pick up CoffeeScript, by writing a small game using CoffeeScript and Canvas. Writing code with CoffeeScript is a very fluent experience, even though I have never used Ruby and have C# background, the syntax feels so natural and code enjoyable to write. All the good things aside, I also got caught by a little gotcha of the language.

In the world of CoffeeScript, global variables must be explicitly declared, using either @ or window keyword, and most tutorials recommend @ due to its succinctness:

@luckyNumber = 4

this attaches luckyNumber into window object and thus accessible globally. The tricky thing is if you do the same declaration in a class:

class MyClass
  constructor: (@luckyNumber = 5) ->

all of sudden, @luckyNumber becomes a property of MyClass, and is not attached to the window object anymore! Now consider following situation:

@luckyNumber = 4
class MyClass 
  constructor: (@luckyNumber = 5) ->

  showLuckyNumber: () ->
    alert(@luckyNumber)

(new MyClass).showLuckyNumber()


Is it going to give you 4 or 5? ... Yes you probably guessed right, it's 5. To access the global variable, you need:

showLuckyNumber: () ->
    alert(window.luckyNumber)

While tricky, this is not exactly a CoffeeScript problem, but weirdness inherited from Javascript. Remember the golden rule: "It's just JavaScript".



1 comment:

  1. It's not that @ has anything to do with global scope; "@" is an alias for "this.". When you use "this" outside of an object scope it defaults to being a reference to window. Expanding on what you concluded, the entire behavior you're discussing is simply a consequence of the way javascript handles "this".

    ReplyDelete