views:

69

answers:

2

Hello,

I asked a question on http://stackoverflow.com/questions/2719643/javascript-this-points-to-window-object regarding "this" points to Window object.

here is source code

var archive = function(){} 

archive.prototype.action = { 
    test: function(callback){ 
        callback(); 
    }, 
    test2: function(){ 
        console.log(this); 
    } 
} 

var oArchive = new archive(); 
oArchive.action.test(oArchive.action.test2); 

Tim Down wrote "but that function is then called using callback(), which means it is not called as a method and hence this is the global object".

What are differences between calling a function by its actual name and callback() as shown on the source code?

How does console.log(this) in test2 points to Window when it is inside archive.action???

+3  A: 

In JavaScript you can invoke functions using 4 different invocation patterns:

  • Function invocation
  • Method invocation
  • Apply/Call invocation
  • Construction invocation

The patterns mainly differ in how the this parameter is initialized.

When you use oArchive.action.test2(), you would be invoking the test2() function with the method pattern, and in this case this would be bound to the action object. JavaScript will use the method pattern whenever the invocation expression contains a refinement (i.e. the . dot expression or the [subscript] expression).

On the other hand, when a function is not the property of an object, then it is invoked using the function pattern. In this case, the this parameter is bound to the global object, and in fact this is how JavaScript is invoking your callback() function.

Douglas Crockford in his Good Parts book, describes this as a mistake in the design of the language, and suggests some possible workarounds. In you case, one easy workaround would be to invoke the callback using call() or apply(), as Tim Down suggested in your previous question:

callback.call(this);

This works because the Apply/Call invocation pattern lets you choose the value of this, which is what you require.

Daniel Vassallo
+1  A: 

In javascript the this keyword is set to the owner of a function. Function objects do not maintain their ownership themselves, instead the ownership is deduced from the way we call a function.

eg:

var foo = function() {
    alert('hello');
};
var abc = {};
abc.bar = foo;

Simply calling the function like

foo();

gives the interpreter no clue about what object the function might be attached to. It may be attached to multiple objects, it may be a variable etc. So the interpreter sets this to the global object.

But however, when calling a function like

abc.bar();

the interpreter knows that function is attached to abc object, therefore this is set to abc. Even if both bar and foo refer to the same function object, the difference in the calling pattern causes this to behave differently.

z33m