2011-12-27 32 views
0

我創建了jQuery對話框類。JavaScript的OOP - 如何參數對象不可見實例方法?

基類是AlertDialog。子類是ChildAlertDialog

當ChildAlertDialog被實例化時,它需要elementId(DOM id)和executor對象(MyExcecutor實例),並用關閉按鈕顯示alert alert對話框。

關閉按鈕觸發MyExecutor的實例方法executeClose();

但是,當我打電話:

alertbox.displayDialog(); 

我得到一個錯誤:

executor is undefined 
executor.executeClose(); 

它的工作原理,如果我通過執行人displayDialog()方法。所以我有點困惑,因爲它可以像Java這樣的其他語言工作,但JavaScript似乎不同。我應該只是通過執行器displayDialog()?或者有更好的方法嗎?

------對話框類------------

//base class 
function AlertDialog(elementId, executor) { 
    this.elementId = elementId; 
    this.height = null; 
    this.width = null; 

    this.displayDialog = function() { 
     $(this.elementId).dialog({ 
      autoOpen: true, 
      height: this.height, 
      width: this.width, 
      buttons: { 
       'close me': function() { 
        executor.executeClose(); //ERROR HERE!!!!! 
       } 
      } 
     }); 
} 

//child class 
function ChildAlertDialog(elementId, executor) { 
    this.elementId = elementId; 
    this.height = 70; 
    this.width = 400; 
} 

//inheritance 
ChildAlertDialog.prototype = new AlertDialog(); 
ChildAlertDialog.prototype.constructor = ChildAlertDialog; 

使用ChildAlertDialog類的類。

function MyExcecutor() { 

    this.execute = function() { 
     //passing elementID and MyExecutor object to ChildAlertDialog 
     var alertbox = new ChildAlertDialog("#someDiv",this); 
     alertbox.displayDialog(); 
    } 

    this.executeClose = function() { 
     //do something when the dialog is closed 
    } 
} 
+1

您將一個執行器傳遞給ChildAlertDialog,但它從未在AlertDialog上設置。 –

+0

但我不想爲我的子類重新定義displayDialog()方法。 –

回答

2

函數參數的範圍只是該函數。在創建對象期間調用ChildAlertDialog構造函數時,executor僅在ChildAlertDialog內可訪問。

爲了保證執行是displayDialog訪問,無論是顯式調用AlertDialog

function ChildAlertDialog(elementId, executor) { 
    AlertDialog.call(this, elementId, executor); 
    this.height = 70; 
    this.width = 400; 
} 

或使executor對話框對象的屬性。

function AlertDialog(elementId, executor) { 
    this.executor = executor; 
    ... 

    this.displayDialog = function() { 
     ... 
        this.executor.executeClose(); 
} 

//child class 
function ChildAlertDialog(elementId, executor) { 
    this.executor = executor; 
    ... 
} 

這個問題,creation of prototypes and object initialization之間缺乏分離的,是什麼導致道格拉斯Crockford的發展Object.create,這正在成爲一個standard,瀏覽器原生JS功能。

function AlertDialog(elementId, executor) { 
    this.elementId = elementId; 
    this.executor = executor; 
} 
AlertDialog.prototype.height = null; 
AlertDialog.prototype.width = null; 
AlertDialog.prototype.displayDialog = function() { 
    $(this.elementId).dialog({ 
     autoOpen: true, 
     height: this.height, 
     width: this.width, 
     buttons: { 
      'close me': function() { 
       this.executor.executeClose(); 
      } 
     } 
    }); 
}; 


//child class 
function ChildAlertDialog(elementId, executor) { 
    AlertDialog.call(this, elementId, executor); 
    this.height = 70; 
    this.width = 400; 
} 

//inheritance 
ChildAlertDialog.prototype = Object.create(AlertDialog.prototype, 
     {constructor: {value: ChildAlertDialog, writable: false, enumerable: false}}); 
1

您重載構造函數,並且從不調用設置它的原始版本。你的第一個構造函數綁定executor在實例的範圍內從未實際運行。所以你必須調用它,語法有點奇怪。

試試這個,它調用原始版本:

//child class 
function ChildAlertDialog(elementId, executor) { 
    // Run the parent constructor function 
    AlertDialog.call(this, elementId, executor); 

    // Child class setup. 
    this.elementId = elementId; 
    this.height = 70; 
    this.width = 400; 
} 

//inheritance 
ChildAlertDialog.prototype = new AlertDialog(); 
ChildAlertDialog.prototype.constructor = ChildAlertDialog; 

你必須以運行實例的構造函數使用ConstructorFunction.call(this, args...)。可悲的原型和構造函數以非常不同的方式繼承。這就是爲什麼在構造函數中設置實例方法通常是個壞主意。