我正在开发一个 Javascript API。它的一部分是一个 JSON 解码器,它接受一个 JSON 字符串,然后构建适当的对象供程序员使用。其中一些对象是 API 中的标准对象,但其中大多数将是这些标准对象的应用程序临时子对象。
这些应用程序特别对象将在 Javascript 开发之前自动生成,并且它们将存在于命名空间中(其名称因应用程序而异)。
假设其中一个 JSON 字符串可以{"Foo":{"bar":"Hello world!"}}
并且应该生成一个Foo
属性bar
具有Hello, world!
值的对象。这个 JSON 解码器将检查是否Foo
是标准原型之一,如果不是,那么它应该检查所有应用程序的临时命名空间(我们可以假设只有一个,但这个问题也适用于多个命名空间)。
所以第一个问题:找到那些命名空间。让我们找到一些选项:
其中一个选项可能是在 JSON 解码器中创建一个方法,该方法存储命名空间以供以后检查(每次创建这些命名空间之一时都应调用此方法)。然而,这引入了一些耦合,因为定义这些名称空间的脚本要求 JSON 解码器已经可用。我不想要这个。
另一种选择可能是有一个全局变量,其中命名空间在构造时注册自己,解码器在那里浏览。此选项与第一个选项非常相似,但它会污染全局命名空间。我不想要这个。
第三种选择可能是以某种方式标记这些命名空间,因此 JSON 解码器可以(在加载时)
window
在本地浏览和存储具有该标签的所有命名空间。例如,这意味着向这些命名空间添加一个属性,IsAFoo
但它必须具有一个在这种情况下根本不会使用的值。然后我们将简单地遍历窗口键并检查是否window[entry].hasOwnProperty("IsAFoo");
存储它们。由于无趣的价值,我不想要这个。我的最后一个选择是让这些命名空间成为“超级命名空间”的一个实例。我们可以想象我们有一个对象将充当命名空间。我们甚至可以让它们继承这个超级命名空间,但这不是必需的。所以让我们再扩展一下第四个选项,因为它是我选择的那个。
想象一下,我们有这个对象,它是标准 API 的一部分,也就是我们所说的“超级命名空间”:
var MyCustomQualifier = function (objects) {
// copy all of the entries to the namespace
for(var entry in objects) {
if(objects.hasOwnProperty(entry)) {
this[entry] = objects[entry];
}
}
};
假设我们有这样的标准 API 对象之一:
var SuperFoo = function () {
};
现在,以下代码将是自动生成的代码,包括命名空间的名称:
var MyGlobalNamespace = MyGlobalNamespace || (function () {
var Foo = function (bar) {
this.bar = bar;
};
Foo.prototype = new SuperFoo();
Foo.prototype.constructor = Foo;
Foo.prototype.say = function () {
return this.bar;
};
return new MyCustomQualifier({
Foo : Foo
});
})();
因此,通过这种方式MyGlobalNamespace
,我们使用标准 API 对象为我们的应用程序获取所有对象,并为其提供自定义业务逻辑。
例如,我们可以执行以下代码来检查一切是否按预期工作:
// this variable would be what the decoder would build,
// but we create it manually here
var foo = new MyGlobalNamespace.Foo("Hello, world!");
console.log("Foo says:", foo.say());
console.log("foo is instance of Foo?", foo instanceof MyGlobalNamespace.Foo);
console.log("foo is instance of SuperFoo?", foo instanceof SuperFoo);
for(var entry in window) {
if(window[entry] instanceof MyCustomQualifier) {
console.log(entry + " is a MyCustomQualifier!");
}
}
它将输出:
Foo says: Hello, world!
foo is instance of Foo? true
foo is instance of SuperFoo? true
MyGlobalNamespace is a MyCustomQualifier!
那么您如何看待这些选项以及我对第四个选项的回答?你有什么额外的方法可以做到这一点吗?代码是纯 Javascript 且没有框架,这一点很重要。
谢谢!