Javascript: got 'undefined' when using 'this' to access outer scope variable in 'private' child function

javascript, scope, this

Solution

Also try this:

function f() {
    var x = [0];
    function f1() { 
        console.log('f1:', this.x, x); 
        f2.call(this); 
    }
    function f2() { 
        console.log('f2:', this.x, x); 
    }
    return { x:x , f1:f1 };
}

var foo = f();    
foo.f1();

This way the context of f2 will be properly set.

In your code `this` in f2 refers to the window object, because f2 wasn't declared as a method. f1 was declared as a method of the returned object when writing `{ x:x , f1:f1 }`. In f2 x is visible not because it is run in the scope of f() but because f2 gets it as a closure. That means in f2, all variables will be visible that was in the same scope when it was created.

What the `this` refers to will be set at invocation time. If you run a function as property of an object like `foo.f1()` it is considered as a method, and `this` will be set to the object. But when you just invoke a function like `f2()` the scope will be the same it was invoked in, in your case it is the window object, because foo is a global in the window object.

In f1 this refers to the hidden f(), therefore if you want f2 also be run in that scope you can use `f2.call(this)`. The argument of .call() will be the `this` of the function when run.

Problem

I have a habit of setting all my variables to its parent scope, instead of calling them implicitly: ``` function outer() { var x, y; function inner() { var x = this.x; x = ...// doing stuff here y = ....// implicit calling parent variable } } ``` so that if I mistype my variable, it won't go to global space. But it seems like declare variable with `this` within private function will return me `undefined`: ``` function f() { var x = [0]; function f1() { console.log('f1:', this.x, x); f2(); } function f2() { console.log('f2:', this.x, x); } return { x:x , f1:f1 }; } var foo = f(); foo.f1(); //output f1: [0] [0] f2: undefined [0] ``` If I understand it correctly, it shouldn't happen, as both `f1` and `f2` should have access to its outer scope by using `this`. Is there any concept I am missing here? Or is it something I just have to live with for now? Update: To clarify, my main concern is why there is the difference between `f1` and `f2`. I prefer to keep `f2` hidden because it will do some internal works, and other developers should not use it when they declare something from `f()`.

Original source