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));