Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closure and this clarification?

Tags:

javascript

I'm encountering with a little problem with the context of this :

In JavaScript this always refers to the "owner" of the function we're executing, or rather, to the object that a function is a method of.

So, this code :

var o={

  f:function ()
     {
       console.log(this); //the owner of the function is `o`
     }
}

console.log(o.f()) // this shows the `o` as this

all OK.

So why this code

var o = {
    f: function ()
    {
        return function ()
        {
            console.log(this);
        }
    }
}
console.log(o.f()())

Shows that this is the global object/window ?

o.f() returns a function , and then I execute it.but still the Hoster object is o. so why it shows the hoster as window?

like image 913
Royi Namir Avatar asked Dec 27 '22 05:12

Royi Namir


2 Answers

The value of this is determined by the object you call the function through, not the place where the function is declared.

For example, if you did the following:

var f = o.f;
console.log(f());

you'd see that this is window as well.

You can also do stuff like this:

var o2 = { f: o.f };
console.log(o2.f());

There, this would be the o2 object, not o.

In your case, o.f is returning a function, which you're invoking without an object reference. In that case, the function invoked is called with this set to the global object (which in a browser is window).

If you want to preserve the this pointer, you'll need to capture it in a closure, like so:

var o = {
    f: function ()
    {
        var self = this;
        return function ()
        {
            console.log(self);
        }
    }
}
console.log(o.f()())

and then you'd have the right object reference regardless of how it's called.

like image 197
Chris Tavares Avatar answered Jan 05 '23 11:01

Chris Tavares


No. The returned function is just a function, not hosted on any object (which makes this default to the global object). Think of that double-invocation as

var temp = o.f();
temp();

Instead of that "owner context" metapher (which fails too often), better refer to MDN's introduction to the this keyword. The "owner" object explanation only works for the case when you call a method on an object - as soon as you pass the function around (into a callback, returning it, assigning it) it looses its context.

like image 23
Bergi Avatar answered Jan 05 '23 11:01

Bergi