我在客户端中声明了一个名称空间和类。实际上,我在几个名称空间中声明了一大堆类。当我从页面加载的服务器上获得一个包含“dotted”namespace.class名称的字符串时,我只需要获取其中一个的实例。
目前我使用eval
来做这件事,但这会导致内存泄漏,所以我试图通过仅知道其名称来寻找实例化声明对象的替代方法。 var obj = "myNamespace.myObjectName"();
之类的东西显然无效。
如果我有一个对象名作为字符串变量,我可以使用eval()
函数来创建该对象的实例:
window["myNamespace"] = {};
myNamespace.myObjectName = function() { /* blah */ };
var name = "myNamespace.myObjectName";
var obj = eval("new " + name + "()");
但由于多种原因,我不想/不能使用eval
。如何在不使用eval
的情况下按名称创建对象?
答案 0 :(得分:1)
听起来你不能控制name
变量的内容,所以你坚持使用.
作为字符串的一部分。
因此,您可以将.split()
字符串放入其名称部分,并使用.reduce()
从基础对象进行遍历。
window["myNamespace"] = {};
myNamespace.myObjectName = function() {
this.foo = "bar"
};
var name = "myNamespace.myObjectName";
var obj = newObjectFromStringPath(name);
document.querySelector("pre").textContent = JSON.stringify(obj, null, 4);
function newObjectFromStringPath(path, base) {
return new (name.split(".").reduce(function(obj, name) {
return obj != null ? obj[name] : null
}, base || window))
}
<pre></pre>
newObjectFromStringPath
被编码为专门定位函数并将其称为构造函数。只需删除该函数中的new
,即可轻松完成此工作以获取任何值。