我有一个非常大的Javascript脚本,其中包含大量全局变量&功能在其中。然后是一段从这个js文件中调用一个函数的代码:myfunc();
好的,现在我克隆了这个脚本并修改了一些功能,所有函数原型和变量在两个脚本中的命名都相同。所以现在我加载了两个脚本,并且一次调用myfunc(),现在我们有一个冲突,因为有大量具有相同名称的全局变量和两个myfunc()s。
我想要做的是将这个克隆的脚本包装在命名空间中,这样我就可以将原始调用修改为:clone.myfunc(),它将调用新函数,但我也希望myfunc()只引用原始剧本。换句话说,我无法触及原始脚本(没有权限),我希望能够在运行时同时使用克隆和原始脚本。
这是我克隆的脚本:http://pastebin.com/6KR5T3Ah
Javascript命名空间似乎相当棘手,这似乎是一个很好的命名空间方法:
var namespace = {
foo: function() {
}
bar: function() {
}
}
...
namespace.foo();
}
然而,这需要使用一个对象,并且脚本(如上所述)在接近4000行时非常庞大,我觉得太过于客观化了吗?
任何人都知道一个更好的解决方案来避免命名空间污染,我只能触摸一个脚本,一个是该脚本的克隆。这样我就可以调用myfunc()和clone.myfunc(),并且所有全局变量都将在其尊重的范围内运行。
或者是,或者我通过并修改所有内容以获得唯一的名称,这可能需要一生的时间
这是一个Mozilla插件,如果它有助于上下文。
感谢。
答案 0 :(得分:6)
通常,您可以轻松地避免污染全局命名空间。如果您的代码如下所示:
var foo;
function bar() {
}
将其包装在函数中并立即调用函数:
(function() {
var foo;
function bar() {
}
})();
现在foo
和bar
被限制在那个大的匿名函数中。它们仍然可以用不合格的名称互相引用,但它们不再是“全局”属性(window
对象上的属性)。这有时被称为在封闭中包装。
您可以通过以下几种方式从该闭包中“导出”:1。返回具有函数属性的对象; 2.如果只需要导出一个函数,只需返回函数引用; 3.明确地将函数分配给闭包内的window
属性:
// 1. Returning an object with function properties:
var myNamespace = (function() {
function myfunc() {
// ...
}
return {
myfunc: myfunc
};
})();
电话会议是myNameSpace.myfunc()
。
// 2. Returning just one function
var myFuncReworked = (function() {
function myfunc() {
// ...
}
return myfunc;
})();
电话会议是myFuncReworked()
。
// 3. Explicitly assign to `window` property:
(function() {
function myfunc() {
// ...
}
window.myfunc = myfunc;
})();
致电myfunc()
(又名window.myfunc()
)。
所有这些都假设脚本不假设它的各种全局变量和函数当然会显示在window
对象上。
This blog post在围绕整个“封闭在封闭”事物的背景方面可能是有用的,尽管帖子的主旨是避免匿名函数(除了作用域函数)。
编辑 Pointy指出这是一个插件(,这是有道理的),所以如果window
不相关,那么第三个选项可以看起来像这样:
// 3. Explicitly assign to global property:
(function(global) { <== Note the new argument
function myfunc() {
// ...
}
global.myfunc = myfunc; <== Use the new arg instead of `window`
})(this); <== Pass `this` into the function
这是有效的,因为在全局范围内,this
指的是全局对象,它本身并没有“名称”;将它传递给函数让我们轻松地给它一个。 (在网页中,window
指的是全局对象,但实际上window
只是上的属性,它用于引用自身的全局对象;技术讨论得到......技术相当快,所以我会留下它,因为我不认为它是超相关的。)
答案 1 :(得分:1)
可能会做两件事:
添加到文件顶部:
(function(global) {
到最后:
})(this);
在声明/定义“myfunc”之后添加:
global['myfunc'] = myfunc;
编辑 - @TJ在他的回答中解释了这一点。