使用模块化方法构建JavaScript应用程序
Structuring a JavaScript app using a modular approach
我正在尝试编写一个javaScript应用程序,它具有足够的大小,模块化可能是一个好主意。我正在使用著名的继承函数,使对象能够从具有参数的构造函数继承。问题是我得到一个错误,父传递到继承函数是未定义的。这是因为,在调用inherit时,还没有定义父构造函数。
我已经想出了一些丑陋的解决方案来解决这个问题:
-
将所有子构造函数声明在父构造函数之后。
-
将所有原型分配绑定到自定义事件,并使用有序的回调链来确保所有原型按顺序分配(也许有可能)。
-
将所有原型赋值从其构造函数所在的代码区域中移出,并将其合并(并放逐)到某个"赋值原型"函数中(是第1项的两倍,不是吗?)
底线是,我不希望在代码中编写构造函数、方法和对象的顺序必须基于代码加载/解释的顺序。我希望我的代码易于扩展,并与相关的代码组合在一起,以便易于理解(即,原型赋值不应该在构造函数声明/定义附近吗?)。
我将模块放在单独的文件中,并使用PHP脚本在它们发送到浏览器之前将它们全部附加在一起。PHP脚本只确保首先包含声明命名空间的文件,然后使用glob将js文件连接起来。
我写了一个小脚本,演示了我所遇到的问题。它是在这个网址上直播的。屏幕是白色的,因为没有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));
谢谢你给我的任何帮助或想法!
克里斯。
我不确定这是合理的做法还是混乱的,但是我创建了一个在文档上触发的自定义事件。准备好并放置在该事件回调中分配原型的所有代码。我知道我正在添加一个事件,当另一个事件被触发时触发(这看起来毫无意义),但我希望自定义事件是一个被监听的事件,以防我想要改变它的触发方式。
/*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));
相关文章:
- MockJax没有在JavaScript应用程序中发送对我AJAX请求的响应
- 如何远程检查JavaScript应用程序的函数调用堆栈
- Windows 8 Javascript应用程序XML对象
- 将javascript应用程序迁移到使用AMD的提示(例如requirejs)
- 如何使用原型继承编写一个整洁灵活的复杂javascript应用程序
- 我如何知道js文件之间的javascript应用程序代码流
- PHP文件没有't从Javascript应用程序获取$_POST
- 在Windows Metro风格的Javascript应用程序中读取文件内容
- 在前端javascript应用程序中使用DI容器有意义吗
- 将一个主要网站转换为javascript应用程序
- 应该如何将密码从纯html/javascript应用程序发送到php页面
- 集成多个JavaScript应用程序
- Windows 8 HTML5 JavaScript 应用程序中向左滑动的事件名称是什么
- 用于组织大型javascript应用程序的工具和最佳实践
- Meteor(JavaScript应用程序平台)|向用户帐户添加数据
- 有没有一种方法可以在IE8中解决我的Rails javascript应用程序.js的问题
- Javascript应用程序作为具有外部依赖关系的AMD模块
- 如何从我的HTML/JavaScript应用程序中引用jQuery
- 基于Rails的javascript应用程序的安全性:如何在渲染的javascript中验证用户的权限
- 使用ajax的javascript应用程序的身份验证模型