1

I created an object with a function that refers to a property of itself using the 'this' keyword.

If I call it normally, it works fine. But if I call pass it as an argument in a forEach function it doesn't work unless I bind it to itself.

Is there a more elegant solution?

Here is an example:

var foobar = {

    foo : function (number) {
       this.bar();
    },

    bar : function () {
        return "string"
    }
};

foobar.foo(0);

[1,2,3].forEach(foobar.foo); //won't work

[1,2,3].forEach(foobar.foo.bind(foobar)); //works

Fiddle: http://jsfiddle.net/q29yatc2/

Kamran224
  • 1,584
  • 7
  • 20
  • 33

2 Answers2

6

@Christos has provided a good explanation of why it happens. However, answering your question, the more elegant solution will be passing foobar as thisArg of forEach:

[1, 2, 3].forEach(foobar.foo, foobar);

Documentation says:

If a thisArg parameter is provided to forEach, it will be passed to callback when invoked, for use as its this value. Otherwise, the value undefined will be passed for use as its this value. The this value ultimately observable by callback is determined according to the usual rules for determining the this seen by a function.

DEMO: http://jsfiddle.net/q29yatc2/4/

Community
  • 1
  • 1
VisioN
  • 143,310
  • 32
  • 282
  • 281
2

Is there a more elegant solution?

I don't think that there is a more elegant solution.

Why this is happening?

This happens due to the change in the context.

This forEach(foobar.foo) doesn't make this to refer to the foobar's instance.

On the other hand calling the bind method you set explicitly where the this would point and this will point to foobar's instance.

From the MDN:

The bind() function creates a new function (a bound function) with the same function body (internal call property in ECMAScript 5 terms) as the function it is being called on (the bound function's target function) with the this value bound to the first argument of bind(), which cannot be overridden. bind() also accepts leading default arguments to provide to the target function when the bound function is called. A bound function may also be constructed using the new operator: doing so acts as though the target function had instead been constructed. The provided this value is ignored, while prepended arguments are provided to the emulated function.

Christos
  • 53,228
  • 8
  • 76
  • 108