How to call an instance method from inside a closure?

coffeescript

Solution

There are various ways to deal with this.

The most common in CoffeeScript would be to use a fat arrow (`=>`) to produce a bound function:

@an_array.map (value) => @a(value)

Demo: http://jsfiddle.net/ambiguous/6BW8q/

The standard JavaScript approaches will also work (and sometimes would be necessary or more appropriate):

Save a reference to `@` so that you don't have to care what `this` is inside the callback function:

_this = @
@an_array.map (value) -> _this.a(value)

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

I tend to use `_this` instead of `self` as the name for this thing due to the existence of `window.self` and the interesting bugs that causes if you forget the `var` in JavaScript.

Manually create a bound function using `Function.bind`, this isn't quite universally supported though:

@an_array.map ((value) -> @a(value)).bind(@)

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

Use jQuery's `$.proxy`, Underscore's `_.bind`, or some other non-native bound function implementation:

@an_array.map _((value) -> @a(value)).bind(@)

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

Which one you choose depends on your environment and specific needs:

- If you're trying to bind a function that comes from elsewhere, then you can't use `=>` so you'll need to use some variant of (2) or (3) above (or possibly `Function.call` or `Function.apply`).

- If you need both the inner and outer `this` at the same time then you'd go with (1).

- If you need to manually bind a function but you aren't sure that a native `bind` exists then you' probably end up with (3) and which branch of (3) would probably depend on which library you already have available.

- ...

- Profit.

Problem

I'm trying to access an instance method inside of a `map` call, unfortunately my reference to the instance object is being redefined to Window. I'm not sure how to get a hold of my instance method: ``` class Test constructor: (@an_array) -> f: () -> @an_array.map (value) -> @a(value) a: (value) -> alert value t = new Test [1, 2, 3] t.f() // TypeError: Object [object Window] has no method 'a' ``` Here's a functional link to the above code

Original source