简体   繁体   中英

Why `this` refers to the parent function's scope

I did read that the this keyword can refer to either the global scope or to the object it is being referred in or to the object to which an event is bound but the below behavior is not understood.

 function outer() { var inner = 4; function innerFunc() { var inner = 5; console.log('inner called with ' + this.inner); } return innerFunc; } var obj = outer(); obj(); 

Why does this log 4 instead of 5. AFAIK this should refer to the function it is being referred in and should be available via closure .

TL;DR - this doesn't work like you think it should.

Read more here , here and here .


The this (otherwise known as context) of a function is determined at call time , not at function definition time. This is widely known as this being dynamically bound , and variables from closure being lexically bound .

var obj = outer();
obj();

Calls outer with this = window (or global in the case of Node.js) because you are not in strict mode (otherwise, this = undefined ). outer doesn't use this , so this doesn't impact it greatly.

outer then returns a function ( innerFunc ), and you assign it to obj . You then call obj , again, with this = window (because you didn't specify anything other with .bind() or .call() or .apply() ).

You then log this.inner which is equivalent to window.inner which is undefined unless you happen to have a global variable named inner with some value.


The value of this , then, is determined by the caller.

If you had invoked obj like so:

obj.call({inner: 42}); // first argument to fn.call() is the context

You would have seen 42 in your console, regardless of how the function was defined.

A way to mitigate this and retain control over your this is to either use fn.bind() or an arrow function .

Your code snippet is returning undefined , not 4. The reason for this is because the window is calling innerFunc by invoking obj() . Thus, this is referring to the window as that is what called innerFunc (and window.inner is undefined ). You can see this by adding a variable inner = 3 at the top of your code (this will make window.inner = 3 ) and so your function will log 3 .

 inner = 3; // ie: window.inner = 3 function outer() { var inner = 4; function innerFunc() { var inner = 5; console.log('inner called with ' + this.inner); // this is window } return innerFunc; } var obj = outer(); obj(); 

In this example you are using a function instead of an object . Additionally, you used a variable instead of the this keyword to assign the value. I think the concept that you're thinking of is local scoping

For example,

function parent(){
var n = 5
    function child(){
         var n = 4 //n is 4 here
    }
//n is 5 here
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM