CoffeeScript newbie here. I’m having a weird problem with the scope of a function that I’ve pushed onto an array and then executed within the class’s member function. Basically, it seems like this isn’t getting set correctly.
class TestClass
constructor: ->
@functions = [] # my array of functions
@member = "hello there! come find me!"
update: =>
func() for func in @functions
testClass = new TestClass
testClass.functions.push( ->
str = "could i find @member? " + @member? + "; this's keys: " + Object.keys(this)
console.log(str)
)
testClass.update()
The result? Strangely enough, it’s:
could i find @member? false; this's keys:
top,location,window,external,chrome,v8Locale,document,$,jQuery,CoffeeScript
It seems like the context in which the function is being called is wrong. I thought that by pushing a skinny-arrow function onto my array, when that function is called it would adopt the context in which it is called (update, where this is the testClass)
Everything works just fine if I do:
update: =>
func.call(this) for func in @functions
but that doesn’t seem very CoffeeScript idiomatic.
By creating your function with the skinny arrow you are creating an anonymous function where
thiswhich will be bound to thewindowobject not the context in which it’s called.thisdoes not maintain it’s value across function calls unless both the functions happen to be bound to the same context.There’s a few ways I can think to solve this problem and although none of them are particularly ugly, none of them are particularly elegant either.
First, is the solution you proposed where you bind the function inside the update function. Second is similar, but moves the binding elsewhere:
Third option would be to use something like the bind function from underscore.js to bind the function to TestClass at the point it’s created. Though that may end up being messier than the other 2 options.