0

我正在嘗試編寫一個足夠大的模塊化大小的javaScript應用程序,這可能是一個好主意。我使用着名的繼承函數來使對象能夠從具有參數的構造函數中繼承。問題是我得到一個錯誤,父進入繼承函數是未定義的。這是因爲,當調用繼承時,父構造函數尚未定義。使用模塊化方法構建JavaScript應用程序

我想出了一些醜陋的解決方案,這一問題:

  1. 聲明其父母畢竟孩子的構造函數(議員)。

  2. 綁定所有原型分配到一個自定義事件,並使用一個有序的回調鏈,以確保所有的原型,以便分配(或許還有潛力那裏)。

  3. 將代碼中的所有原型任務從其構造函數生存併合並(並放逐)到某個「賦值原型」函數(兩倍於第一項,不是?)。

底線是,我不希望有燈座,其中我的構造函數,方法和對象都寫在代碼中的代碼加載/解釋訂單上的順序。我希望我的代碼可以很容易擴展,並將相關的代碼組合在一起,這樣很容易理解(即原型分配不應該在構造函數聲明/定義附近?)。

我將模塊放置在單獨的文件中,並使用PHP腳本在發送到瀏覽器之前將它們附加在一起。 PHP腳本只確保首先包含聲明名稱空間的文件,然後將js文件與glob連接起來。

我寫了一個小腳本,演示了我正在遇到的問題。它是is live at this url。屏幕是白色的,因爲沒有html - 我在這裏使用控制檯進行分析。

/*global console, jQuery, $, myNS: true*/ 
/*jslint browser: true*/ 

/* 
* This file is deliberately set as the first file in the php glob. 
*/ 
var myNS = (function (myNS, $, window, undefined) { 
    "use strict"; 

    /* 
    * @param {object} coords -- e.g. {x: 3, y: 26} 
    */ 
    myNS = function (coords) { 
     return new myNS.CartesianLoc(coords); 
    }; 

    // static methods 
    myNS.inherit = function (parent) { 
     function F() {} 
     F.prototype = parent.prototype; 
     return new F(); 
    }; 
    myNS.getWinCenter = function() { 
     return { 
      x : $(window).width()/2, 
      y : $(window).height()/2 
     }; 
    }; 

    // prototype 
    myNS.prototype = { 
     log: function() { 
      if (window.console) { 
       console.log(this); 
      } 
     } 
    }; 

    return myNS; 
}(myNS, jQuery, window)); 



/* 
* This is another file. 
*/ 
(function (myNS, $, window, undefined) { 
    "use strict"; 
    /* 
    * CartesianLoc constructor 
    * 
    * @param {object} coords -- given in a conceptual 
    * Cartesian space where the origin (0,0) is 
    * the middle of whatever screen 
    */ 
    function CartesianLoc(coords) { 
     myNS.Loc.call(this, coords); 
    } 
    CartesianLoc.prototype = myNS.inherit(myNS.Loc); 
    CartesianLoc.prototype.constructor = CartesianLoc; 

    CartesianLoc.prototype.getWinCoords = function() { 
     return { 
      x: myNS.getWinCenter().x + this.x, 
      y: myNS.getWinCenter().y + this.y 
     }; 
    }; 

    myNS.CartesianLoc = CartesianLoc; 
}(myNS, jQuery, window)); 



/* 
* This is another file. 
*/ 
(function (myNS, $, window, undefined) { 
    "use strict"; 
    // Location constructor 
    function Loc(coords) { 
     this.x = coords.x; 
     this.y = coords.y; 
    } 
    Loc.prototype = myNS.inherit(myNS); 
    Loc.prototype.constructor = Loc; 

    Loc.prototype.translate = function (coords) { 
     this.loc.x += coords.x; 
     this.loc.y += coords.y; 
     return this; 
    }; 

    myNS.Loc = Loc; 
}(myNS, jQuery, window)); 



/* 
* Application js file 
* 
*/ 

(function (myNS, $, window, undefined) { 
    "use strict"; 

    $(document).ready(function (event) { 
     if (console) { 
      console.log("%o", new myNS({x: 100, y: -45})); 
     } 
    }); 

}(myNS, jQuery, window)); 

感謝您的任何幫助或想法,你可以給我!
克里斯

回答

0

我不知道這是否是一個正確的做法或凌亂,但我創建了一個上的document.ready觸發自定義事件,並放置所有在回調到該事件的原型分配的代碼。我知道我添加了一個事件,當另一個事件被觸發時(這在表面上看起來毫無意義)會觸發,但是我希望自定義事件是一個被監聽的事件,以便在我想要改變稍後被觸發的方式時使用。

/*global console, jQuery, $, myNS: true*/ 
/*jslint browser: true*/ 

/* 
* This file is deliberately set as the first file in the php glob. 
*/ 
var myNS = (function (myNS, $, window, undefined) { 
    "use strict"; 

    /* 
    * @param {object} coords -- e.g. {x: 3, y: 26} 
    */ 
    myNS = function (coords) { 
     return new myNS.CartesianLoc(coords); 
    }; 

    // Triggered after all constructors have been defined 
    $(document).ready(function (event) { 
     $(document).trigger("myNS"); 
    }); 

    // static methods 
    myNS.inherit = function (parent) { 
     function F() {} 
     F.prototype = parent.prototype; 
     return new F(); 
    }; 
    myNS.getWinCenter = function() { 
     return { 
      x : $(window).width()/2, 
      y : $(window).height()/2 
     }; 
    }; 

    // prototype 
    myNS.prototype = { 
     log: function() { 
      if (window.console) { 
       console.log(this); 
      } 
     } 
    }; 

    return myNS; 
}(myNS, jQuery, window)); 



/* 
* This is another file. 
*/ 
(function (myNS, $, window, undefined) { 
    "use strict"; 
    /* 
    * CartesianLoc constructor 
    * 
    * @param {object} coords -- given in a conceptual 
    * Cartesian space where the origin (0,0) is 
    * the middle of whatever screen 
    */ 
    function CartesianLoc(coords) { 
     myNS.Loc.call(this, coords); 
    } 
    $(document).on('myNS', function (event) { 
     CartesianLoc.prototype = myNS.inherit(myNS.Loc); 
     CartesianLoc.prototype.constructor = CartesianLoc; 

     CartesianLoc.prototype.getWinCoords = function() { 
      return { 
       x: myNS.getWinCenter().x + this.x, 
       y: myNS.getWinCenter().y + this.y 
      }; 
     }; 
    }); 
    myNS.CartesianLoc = CartesianLoc; 
}(myNS, jQuery, window)); 



/* 
* This is another file. 
*/ 
(function (myNS, $, window, undefined) { 
    "use strict"; 
    // Location constructor 
    function Loc(coords) { 
     this.x = coords.x; 
     this.y = coords.y; 
    } 
    $(document).on('myNS', function (event) { 
     Loc.prototype = myNS.inherit(myNS); 
     Loc.prototype.constructor = Loc; 

     Loc.prototype.translate = function (coords) { 
      this.loc.x += coords.x; 
      this.loc.y += coords.y; 
      return this; 
     }; 
    }); 
    myNS.Loc = Loc; 
}(myNS, jQuery, window)); 



/* 
* Application js file 
* 
*/ 

(function (myNS, $, window, undefined) { 
    "use strict"; 

    $(document).ready(function (event) { 
     if (console) { 
      console.log("%o", new myNS({x: 100, y: -45})); 
     } 
    }); 

}(myNS, jQuery, window));