0

Hi I'm new to Js and Coffeescript, here's a situation I feel difficult to refer the property of parent object which is App in the following example

App =
  init: ->
    this.foo = 'bar'
    this.bindEvent()
  bindEvent: ->  
    $('#test').click(this.show)
  show: ->
    alert this.foo

App.init()

I think the fat arrow may do the trick but once I've changed to show: =>, this in the context of show method refers to the window object, instead of App object that I want to . Anybody can tell me how to do it right?

http://jsfiddle.net/kZpHX/

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
mko
  • 21,334
  • 49
  • 130
  • 191
  • Have a look of this answer for a discussion of the fat arrow. http://stackoverflow.com/questions/13184209/when-does-the-fat-arrow-bind-to-this-instance/13184211#13184211 to se – robkuz Feb 18 '13 at 07:45

1 Answers1

3

When you define your show function, @ (AKA this) actually is window so

show: => console.log(@)

will bind show to window. The problem is that you're simply defining an object so there isn't anything to bind to: you aren't defining a class so this is window. You could refer to App explicitly like this:

App =
  #...
  show: -> alert(App.foo)

Demo: http://jsfiddle.net/ambiguous/3sRVh/

The this.foo in init will do the right thing because saying App.init() sets up the expected this.

You could also hook up the desired this manually:

bindEvent: ->
  $('#test').click => @show()

# or
bindEvent: ->
  _this = @ # JavaScript style
  $('#test').click -> _this.show()

Demos: http://jsfiddle.net/ambiguous/byL45/, http://jsfiddle.net/ambiguous/MT8fG/

Or you could create a class for your App instead:

class App
  constructor: ->
    @foo = 'bar'
    @bindEvent()
  bindEvent: ->  
    $('#test').click(@show)
  show: =>
    console.log(@foo)

new App

That way your show: => will behave the way you expect it to.

Demo: http://jsfiddle.net/ambiguous/byatH/

mu is too short
  • 426,620
  • 70
  • 833
  • 800