Reputation: 3457
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()
.
Upvotes: 3
Views: 2364
Reputation: 1391
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.
Upvotes: 4
Reputation: 96810
You returned this from the function:
{ x : x, f1 : f1 }
This sets the the this
objects properties to the above. f2
is not apart of the object so it can't access the this
that it refers to.
Upvotes: 0
Reputation: 2565
When your f
function returns an object, it doesn't have f2
method. f2
method is an inner method of f
and exists only in its scope.
If you use this code:
function f() {
var x = [0];
function f1() {
console.log('f1:', this.x, x);
this.f2();
}
function f2() {
console.log('f2:', this.x, x);
}
return { x:x , f1:f1, f2:f2};
}
var foo = f();
foo.f1();
then this
in f1
method will have access to the f2
method of this
, and object's f2
method will return the correct x
.
Upvotes: 0