所以我是一个相当不错的javascript程序员,我刚刚完成了一个相当大的Web应用程序,涉及编写相当多的javascript。我调试脚本时可以遇到的一件事就是我在脚本中使用的各种全局变量存在一些命名空间冲突。基本上,我的javascript文件的结构如下:
global var a
global var b
global var c
function1(){}
function2(){}
function3(){}
使用jQuery文档就绪函数将各种事件绑定到我的html中的按钮,并将我的函数作为事件处理程序回调调用。
有些人建议将我的整个脚本封装在一个巨大的函数中,以防止任何与范围相关的错误。我无法弄明白究竟会带来什么。任何提示都很受欢迎,因为我即将创建另一个Web应用程序,它将涉及相当多的AJAX页面加载,以避免浏览器刷新和绑定到各种事件的DOM操作。谢谢!
答案 0 :(得分:3)
我建议阅读jQuery插件创作指南(如果你不是,我建议你考虑使用jQuery)
http://docs.jquery.com/Plugins/Authoring
顺便提一下这次被问过多次(不是批评重新提问)
我还强烈建议您阅读有关注册DOM事件的jQuery live插件(我猜它现在是内置的): http://api.jquery.com/live/ (这将最大限度地减少对解绑和重新绑定DOM节点的状态管理的迫切需要)。
答案 1 :(得分:3)
我喜欢在匿名函数中包装每个文件的内容。然后,您可以将window
作为参数传递给它,并有选择地从每个文件中选择要导出的内容。
(function(exports) {
var MyClass = function() {
};
MyClass.prototype.method = function() {
};
// this won't be visible outside this file
var helperFunction = function() {
};
exports.module = exports.module || {};
exports.module.MyClass = MyClass;
})(window);
此外,您可以通过以下方式构建它,以便将this
用作全局对象,如果它对您的编码风格更有吸引力:
(function() {
this.Thing = function() { };
}).call(window);
答案 2 :(得分:3)
迈克尔和nnnnnn版本的类似替代方案是
var YourApp = {
a: 1234,
b: 5678,
function1: function () {
},
etc
};
YourApp是唯一的全局变量,其属性可以像
一样访问YourApp.function1();
或
YourApp.a;
答案 3 :(得分:2)
我希望从OO纯粹主义者中获得支持,但是......
命名空间冲突的一个非常简单的解决方案是将变量和函数放入一个类中,即使它没有工作构造函数或执行它自己的任何内部处理。
function YourApp() {} // empty constructor...
YourApp.a = 1234;
YourApp.b = 5678;
YourApp.function1 = function() {};
YourApp.function2 = function() {};
function YourOtherApp() {} // empty constructor...
YourOtherApp.a = 1234;
YourOtherApp.b = 5678;
YourOtherApp.function1 = function() {};
YourOtherApp.function2 = function() {};
// Then you call it like:
YourApp.function1();
// And you have no more namespace collisions with other globals
答案 4 :(得分:2)
基于您过去使用大量全局变量和函数所做的最快的第一步是简单地将所有这些变为功能并使它们成为单个对象的属性。该单个对象被声明为全局变量,但它是您的唯一全局变量,实际上是您的新命名空间,因此您只需担心一个名称可能与其他库发生冲突。
所以直接将你与a,b等给出的例子联系起来:
var SNS = {}; // create some namespace object
SNS.a = "something";
SNS.b = "something else";
SNS.c = 17;
SNS.method1 = function(x) {
alert(SNS.a + x);
};
SNS.method2 = function() {
SSN.method1(12); // call another function
};
SNS.SUB = {};
SNS.SUB.property1 = "sub namespace prop 1";
SNS.SUB.method1 = function() {};
// etc.
我的例子使用'SNS'作为'some namespace';我相信你可以立即看到如何轻松应用你刚刚完成的项目。您可能还会看到一个缺点,即您的方法相互引用和变量,您必须在它们前面加上对象的名称。如果您的子命名空间变得更糟。幸运的是,有很多方法,但我宣称它们超出了这个答案的范围。
说了这么多,让你阅读(谷歌)的东西是“揭示模块模式” - 将帮助你多做一些OO(如果这就是你想要的)。
您可以在此处找到对问题的深入解答:http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/
进一步阅读: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth