Chris Muench
Chris Muench

Reputation: 18318

Why does storing a reference to a function then calling the function cause 'this' to have a context of window?

I am reading a tutorial at so I can understand _.bind and _bindAll: http://blog.bigbinary.com/2011/08/18/understanding-bind-and-bindall-in-backbone.html

The website has the following code

function Developer(skill) {
  this.skill = skill;
  this.says = function(){
    alert(this.skill + ' rocks!');
  }
}
var john = new Developer('Ruby');
john.says(); //Ruby rocks!

vs

function Developer(skill) {
  this.skill = skill;
  this.says = function(){
    alert(this.skill + ' rocks!');
  }
}
var john = new Developer('Ruby');
var func = john.says;
func();// undefined rocks!

Why does storing a reference to a function then calling the function cause this to have a context of window?

Upvotes: 1

Views: 52

Answers (2)

Denys Séguret
Denys Séguret

Reputation: 382132

When you execute

a.b();

then a is the context of execution of b (this inside b) unless b is a bound function.

If you don't have a, that is if you have

b();

then it's the same as

window.b();

so window is the context of execution of b.

Note also that

a.b();

is the same as

b.call(a);

and

b();

is the same as

b.call(); // call replaces its first argument by the global object if it's null or undefined

If you want to bind the context, then you can do (on modern browsers)

var func = john.says.bind(john);
func();

or (more classically) use a closure :

var func = function(){john.says()};
func();

Upvotes: 2

maerics
maerics

Reputation: 156424

Because the "this" keyword is bound at call time, not definition time.

When you call john.says() it's like doing john.says.apply(john).

When you call func() it's like doing func.apply().

Yehuda Katz has a great explanation of "JavaScript function invocation and this".

Upvotes: 2

Related Questions