1

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.

0

1 Answer 1

1

By creating your function with the skinny arrow you are creating an anonymous function where this which will be bound to the window object not the context in which it's called. this does 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:

class TestClass
    ...
    addFunc: (func) ->
        @functions.push( => func.call( @ ) )

testClass.addFunc( -> ... )

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Alright, just wanted to make sure there wasn't a more elegant way of doing this. I think I'll go with your second solution. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.