Javascript命名空间帮助

时间:2010-05-31 21:13:02

标签: javascript

我有一个非常大的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插件,如果它有助于上下文。

感谢。

2 个答案:

答案 0 :(得分:6)

通常,您可以轻松地避免污染全局命名空间。如果您的代码如下所示:

var foo;

function bar() {
}

将其包装在函数中并立即调用函数:

(function() {
    var foo;

    function bar() {
    }
})();

现在foobar被限制在那个大的匿名函数中。它们仍然可以用不合格的名称互相引用,但它们不再是“全局”属性(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)

可能会做两件事:

  1. 在函数中包装所有内容
  2. 明确曝光您的“myfunc”
  3. 添加到文件顶部:

    (function(global) {
    

    到最后:

    })(this);
    

    在声明/定义“myfunc”之后添加:

    global['myfunc'] = myfunc;
    

    编辑 - @TJ在他的回答中解释了这一点。