2014-01-09 140 views
1

我是JavaScript的面向對象編程(來自C++領域)的新手。調用構造函數的成員函數

我想知道從構造函數調用成員函數的最佳做法。

以下是一段代碼: 很明顯,「initialize」是在調用「this.initialize();」之前聲明的。

function Foo() { 
    this.initialize = function() { 
     alert("initialize");  
    }; 

    this.hello = function() { 
     alert("helloWorld"); 
     this.initialize(); 
    }; 

    this.initialize(); 
}; 
var f = new Foo(); 
f.hello(); 

如果我更改了以下代碼,它將在「this.initialize();」時失敗。

問題1這是爲什麼? JavaScript引擎不會首先讀取對象的所有成員函數聲明嗎?

function Foo() { 
    this.initialize();    //failed here 
    this.initialize = function() { 
     alert("initialize");  
    }; 

    this.hello = function() { 
     alert("helloWorld"); 
     this.initialize(); 
    }; 
}; 
var f = new Foo(); 
f.hello(); 

然後我做了這樣的改變。

函數「初始化」在構造上執行,但函數「hello」中調用「this.initialize()」失敗。

function Foo() { 
    this.initialize = function() { 
     alert("initialize");  
    }(); 

    this.hello = function() { 
     alert("helloWorld"); 
     this.initialize();  //failed here 
    }; 
}; 

var f = new Foo(); 
f.hello(); 

問題2:是的代碼的第一塊從構造主叫成員函數的必由之路?

更新:

,如果我必須在使用之前定義的函數,問題3:爲什麼下面的代碼工作?

function Foo() { 
    this.hello = function() { 
     alert("helloWorld"); 
     this.initialize(); 
    }; 
    this.initialize(); 
}; 

Foo.prototype.initialize = function() { 
    alert("initialize"); 
}; 

var f = new Foo(); 
f.hello(); 

問題4: 爲什麼下面的代碼成功了嗎? (考慮 「未來」 函數被調用後所定義)

alert("The future says: " + future()); 

function future() { 
    return "We STILL have no flying cars."; 
} 
+2

您必須在調用它之前定義函數,因此您的第二個代碼將不起作用。此外,第三個(最後一個)將不起作用,因爲**初始化**不是函數,因爲你在末尾有'()',這是一個返回值 – Cilan

回答

1

調用從構造的方法:

var f = new Foo(); 

function Foo() { 
    this.initialize();    //failed here 

}; 
Foo.prototype.initialize = function() { 
    alert("initialize");  
}; 

執行處理:

1) All functions are created (that are defined at the root) 
2) Code is executed in order 
3) When Foo is created/constructed it executes the code. 
    It try's to run Initialize() but it doesn't find it, 
    it throws an internal exception that is caught and 
    then creates the Prototype method and executes it. 
4) If the Foo.Prototype.initialize line came BEFORE the, 
    "var f = new Foo()" then the initialize function would have existed. 

此過程發生執行的每一行。

+0

我知道這個是有效的,爲什麼?從字面上看,它不是在被調用的地方之後定義的函數嗎? – milesma

+0

將編輯我的答案。 –

+0

執行順序很重要,這就是爲什麼當你在Foo中定義Initialize()方法然後調用this.Initialize()時它就起作用了。 –

3

在第一種情況下,您在定義之前(在下一行)呼叫initialize

在第二種情況下,您將函數的返回值(在這種情況下爲undefined)分配給this.initialize,因此當您稍後嘗試將其作爲函數調用時,會出現錯誤。

您可能想要進一步研究製作類結構的原型模式 - 道格拉斯克羅克福德在這方面寫了很多有用的東西,對介紹性學習很有用:http://javascript.crockford.com/prototypal.html是一個好的開始。

+0

** + 1 **我有這種總是評論答案的愚蠢情況,而不是發佈答案 – Cilan

+0

我通常會做同樣的事情;特別是因爲在沒有花費更多時間的情況下在移動設備上編寫好的答案就困難得多了...... – Krease

3

我的回答直列(種)

問題1,這是爲什麼?JavaScript引擎不會首先讀取對象的所有成員函數聲明嗎?

不,如果它們在您的示例中定義,它們將按順序執行,因爲該方法尚不存在,它將拋出。

這種方式將是一個不同的情況下(不是OO,但是ilustrate):

function Foo(){ 
    initialize(); //This would work 
    function initialize(){ ... } //Parser defines its function first 
} 

在這種情況下,解析器不先定義函數聲明,這是一個不同的情況。

函數「初始化」在構造上執行,但函數「hello」中調用this.initialize()失敗。

this.initialize = function() { 
    alert("initialize");  
}(); //This executes the function! 

與上面的代碼的問題是,你並沒有使用該功能this.initialize,你要指定其執行的結果,在這種情況下undefined(因爲裏面的沒有return功能)

例如,如果代碼是:

this.initialize = function() { 
    return 2; 
}(); 

然後this.initialize會... 2 !! (不是功能)。

希望這會有所幫助。歡呼聲

相關問題