0

我正在编写一个库,我使用“lib.someFunction();”调用所有函数 或“lib.someVariable;”。我知道我不应该污染全局命名空间,但我想给我图书馆的用户这个选项。我听说有些库有一个“选项”,比如“installLibrary();” 将类中的所有函数和变量移动到全局命名空间。

这样,只有用户更喜欢这样才能调用“someVariable”;或“someFunction();” 直接地。

不过,我的问题是如何编写这样的函数。有任何想法吗?

4

2 回答 2

1

除了不使用库污染全局空间的明显原因之外,我相信您可以执行以下操作。

注意:我写这个是为了看看我们是否在浏览器或节点中。您应该能够在浏览器中引用“window”,在节点中为全局命名空间引用“global”。

var scope = (typeof window !== 'undefined' ? window : global);
scope.someVariable = true;
scope.someFunction = function() { };

// Essentially, this is the same as:
window.someFunction = function() { };
// or
global.someFunction = function() { };
于 2012-11-28T19:06:41.790 回答
1

您可以执行以下操作:

function Library() { 
    this.var = 5; 
    this.otherVar = 4; 
    this.cool = function(x) {
        return x + this.otherVar;
    }
} 
var library = new Library();

(function (lib, context) {
    for (var prop in lib) {
        if (lib.hasOwnProperty(prop) && prop) {
            if (typeof lib[prop] == "function") {
                context[prop] = function() {
                    return lib[prop].apply(lib, arguments);
                }
            } else {
               context[prop] = lib[prop]; 
            }
        }
    }
}(library, this));

但要注意在这里使用除函数以外的任何东西。如果您这样做并尝试调整全局/窗口命名空间上的参数,它们将不会被带回您的库函数,并且可能无法获得您想要的行为。例如:

library.cool(3);  // 7
cool(3);          // 7
otherVar = 10;
library.cool(3);  // 7
cool(3);          // 7  Still?
library.otherVar = 10;
library.cool(3);  // 13
cool(3);          // 13  Finally!

没有此限制的替代方法是将您的库构造函数应用于全局/窗口对象:

Library.call(this);

这样做的问题在于,您不仅会使用公共 API 污染全局范围,而且还会使用沿途存储在本地闭包中的任何内容。这让我觉得太重了。

如果您的库使用类似显示模块模式并且只公开函数,那么我认为第一个非常简单。但正如其他人所说,这可能并不明智。最多,我会为用户提供这个选项,但要警告不要这样做。

于 2012-11-28T20:06:12.183 回答