Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript "this" points to Window object again

I asked a question on 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???

like image 795
Moon Avatar asked May 02 '10 02:05

Moon


People also ask

What does the this keyword indicate in JavaScript?

In JavaScript, the this keyword refers to an object. Which object depends on how this is being invoked (used or called). The this keyword refers to different objects depending on how it is used: In an object method, this refers to the object. Alone, this refers to the global object.

Why this keyword is undefined in JavaScript?

A variable that has not been assigned a value is of type undefined . A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned .

How do you check if a function is executed in JavaScript?

Using the typeof Operator In JavaScript, the typeof operator is useful to check the type of the variable, function, objects, etc. When we use the function name as the operand of the typeof variable, it returns the 'function' string, and we can check whether the function is defined.


2 Answers

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.

like image 96
Daniel Vassallo Avatar answered Nov 02 '22 22:11

Daniel Vassallo


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.

like image 39
z33m Avatar answered Nov 03 '22 00:11

z33m