JavaScript Closure problem again!
This is what i am facing with
function AAA(){ this.f1 = function (){ /*expecting that f2 will be call as both of then are of same object.*/ console.log(f2(5));// } this.f2 = function(x){ return x; } } x = new AAA(); x.f1(); //ReferenceError: f2 is not defined
Neither does it work,
function AAA(){ this.f1 = function (){ /*expecting that f2开发者_JS百科 will be call as both of then are of same object.*/ console.log(f3(5));// } /*naming the function f3 hope to get function reference, as function on the right side has name now and in the closure of f1, right?*/ this.f2 = function f3(x){ return x; } function f4() {}; } x = new AAA(); x.f1(); //ReferenceError: f3 is not defined
What is happening here? who are in closure of 'f1' except 'f4'? can't we call the same object function without 'this'?
You are not really using closures here. It will work fine if you change the line to
console.log(this.f2(5));
If you want to use closures, you can rewrite the class as follows:
function AAA()
{
var f1 = function()
{
console.log(f2(5));
};
// f2 is a private function.
var f2 = function(x)
{
return x;
};
// Define the public interface.
return { f1: f1 };
}
You’re confusing a few things here; this
and closures are two completely different issues.
Your problem here is that you’re trying to refer to f2
directly, thereby assuming that this
is part of the current execution scope. It isn't.
If you put f2
on this
, you’ll have to keep referencing it as this.f2
. To be able to reference f2
directly, you’ll have to declare a (separate) variable by that name, which you can then assign to this
if you want, as qwertymk says.
Personally, I try to avoid this
as much as I can, since its meaning is completely dependent on how the function is called (e.g. if AAA
is called without specifying the new
operator, this
will refer to the global object!). It also saves you from headaches like the one above. Closures (as demonstrated by Elian) are a much better way of obtaining this functionality.
Interestingly enough, I've found I hardly ever need to use this
.
In Elian's example, f2
is closed over: once the AAA function is done running, nobody can access f2, except the functions that were defined inside AAA (and are still accessible). In this case, the function f1
is accessible from the returned object, so that still exists. Therefore, f1
can still use f2
.
That's what closures are about: a function can still access all the variables in its scope, even when those variables were declared in a function that's terminated.
It should be this.f2()
not f2()
by itself. You would use f2()
if it was a private variable which means if it was created with a var
keyword.
function AAA(){
var f3 = function(x) { return x; };
this.f1 = function (){
/*expecting that f2 will be call as both of then are of same object.*/
console.log(this.f2(5));//
console.log(f3(10));
}
this.f2 = function(x){
return x;
}
}
DEMO
Others have already told you what the problem is, so i will not repeat it. If you want your code to work, you just need a reference to this:
function AAA(){
var self = this;
this.f1 = function (){
console.log(self.f2(5)); //self.f2 exists, yay
}
this.f2 = function(x){
return x;
}
}
x = new AAA();
x.f1(); //5
精彩评论