Skip to content Skip to sidebar Skip to footer

Why Do I Lose The Context Of This In Javascript?

I have this simple code : var o = { a: 1, b: 2, f1: function () { alert(this.b); } } var o2 = { a: 11, b: 22, f2: function (j) {

Solution 1:

I found Crockford had an excellent description of the way this works. Functions in JavaScript can be invoked in 4 styles :

  1. The "function" style
  2. The "method" style
  3. The "Constructor" style
  4. The "call or apply" style.

I might be getting the exact names wrong there, but the spirit is the same. You should definitely get the book "JavaScript: The Good Parts" if you don't have it.

So anyway - on to your question. The key thing is that the value if "this" is dependant on which style you use.

// function invocation style, var f = function() { console.debug(this); }
f(); // "this" is bound to the global object.// "method" invocation stylevar obj = {
    f: function() { console.debug(this); }
};

obj.f(); // "this" is bound to "obj", the object on which the function was invoked// so important bit is :var f = obj.f;
f(); // "this" is global object
obj.f() // "this" is obj

In your example you are losing "this" because of the way you are invoking the function.

Solution 2:

If you do it like as follows,

function will be called in o2 context

var o2 = {
    a: 11,
    b: 22,
    f2: function (j){
      this.temp = j;
      this.temp();
    }
};

also these will work too:

f2: function (j){
      j.apply(this);
}

f2: function (j){
      j.apply(o2);
}

Otherwise you call it just like an ordinary function out of context.

j Is ripped out of its context and you did no tricky closures on it(which is not your intent) so for making "this" work in it you need a scope. The this scope in your question for j is window, which has no "b" in it therefore you get an "undefined".

Solution 3:

Check this tests:

o.f1(); // alerts 2

var f3 = o.f1; // (*)f3(); // alerts undefined

o2.f2(f3); // alerts undefined

f3.apply(o2); // alerts 22

I realize that when you pass a function as parameter the context is lost exactly the same way it's lost in the (*) pointed in the code above.

What happening is j = arguments[0] = o.f1 and at this point you lose the context.

When passes a function as a parameter you are just passing the reference in memory to that function. Without bind the context you'll fail the simple j() call. That's why you need to use apply or the this trick showed by Ihsan.

Post a Comment for "Why Do I Lose The Context Of This In Javascript?"