开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜