我正在编写一个库,我使用“lib.someFunction();”调用所有函数 或“lib.someVariable;”。我知道我不应该污染全局命名空间,但我想给我图书馆的用户这个选项。我听说有些库有一个“选项”,比如“installLibrary();” 将类中的所有函数和变量移动到全局命名空间。
这样,只有用户更喜欢这样才能调用“someVariable”;或“someFunction();” 直接地。
不过,我的问题是如何编写这样的函数。有任何想法吗?
我正在编写一个库,我使用“lib.someFunction();”调用所有函数 或“lib.someVariable;”。我知道我不应该污染全局命名空间,但我想给我图书馆的用户这个选项。我听说有些库有一个“选项”,比如“installLibrary();” 将类中的所有函数和变量移动到全局命名空间。
这样,只有用户更喜欢这样才能调用“someVariable”;或“someFunction();” 直接地。
不过,我的问题是如何编写这样的函数。有任何想法吗?
除了不使用库污染全局空间的明显原因之外,我相信您可以执行以下操作。
注意:我写这个是为了看看我们是否在浏览器或节点中。您应该能够在浏览器中引用“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() { };
您可以执行以下操作:
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 污染全局范围,而且还会使用沿途存储在本地闭包中的任何内容。这让我觉得太重了。
如果您的库使用类似显示模块模式并且只公开函数,那么我认为第一个非常简单。但正如其他人所说,这可能并不明智。最多,我会为用户提供这个选项,但要警告不要这样做。