2011-02-17 96 views
0

這就是我面臨着JavaScript關閉問題再次發生!

 
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 

它也不工作,

 
function AAA(){ 
    this.f1 = function(){ 
     /*expecting that f2 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 

這到底是怎麼回事?除'f4'之外誰在關閉'f1'?我們不能在沒有'this'的情況下調用相同的對象函數嗎?

回答

1

它本身應該是this.f2()而不是f2()。如果它是一個私有變量,則表示它是否使用var關鍵字創建,則使用f2()

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

+0

整整提到的原因qwertymk:分配給`this.f2`不創建一個名爲變量`f2`,但你的代碼試圖訪問名爲`f2`的變量(!)。 – 2011-02-18 10:03:20

+0

@Chistopher當我將函數命名爲f3時,第二個例子會發生什麼? – Zer001 2011-02-20 08:08:47

3

你是不是真的使用閉包在這裏。這將正常工作,如果你,如果你想使用封閉行更改爲

console.log(this.f2(5)); 

,你可以重寫類,如下所示:

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 }; 
} 
2

你在這裏混淆了一些東西; this和關閉是兩個完全不同的問題。

你的問題在於你試圖直接引用f2,因此假設this是當前執行範圍的一部分。 這不是
如果您將f2放在this上,則必須將其引用爲this.f2。爲了能夠直接引用f2,您必須聲明一個(單獨的)變量的名稱,然後您可以將其分配給this(如qwertymk所述)。

就個人而言,我會盡量避免this像我可以,因爲它的意義是完全依賴於該函數的調用(例如,如果AAA被稱爲不指定new操作,this將引用全局對象!) 。它還可以讓你免受上述的麻煩。關閉(如Elian所示)是獲得此功能的更好方式。
有趣的是,我發現我幾乎沒有需要使用this

在埃連的例子,f2關閉了:一旦AAA功能完成運行時,沒有人可以訪問F2,除了內部AAA中定義的(並且仍然可以訪問)功能。在這種情況下,函數f1可以從返回的對象訪問,所以仍然存在。因此,f1仍然可以使用f2
這就是閉包的作用:一個函數仍然可以訪問其作用域中的所有變量,即使這些變量是在終止函數中聲明的。

0

其他人已經告訴過你問題是什麼,所以我不會重複。如果你希望你的代碼工作,你只需要這一個參考:

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