获取构造函数函数的最佳方式是在JavaScript中使用带名称空间的字符串表示

Best way to get a constructor function for its namespaced, string representation in JavaScript

本文关键字:空间 表示 字符串 JavaScript 最佳 函数 构造函数 方式 获取      更新时间:2023-09-26

如果我有一个像"AppNamespace.SomeObject.ClassName"这样的字符串,并且我知道该字符串表示实际的构造函数,那么在像var foo = new AppNamespace.SomeObject.ClassName这样的语句中使用它的最佳/推荐方法是什么?

我可以做:

var s = "AppNamespace.SomeObject.ClassName"
var foo = new (eval(s))

或者类似的东西:

var parts = "AppNamespace.SomeObject.ClassName".split(".")
var foo = new (window[parts[0]][parts[1]][parts[2]])

但我想知道是否有更好的解决方案不涉及eval或必须拆分字符串并在其各个部分中循环。有人有什么想法吗?如果没有,根据我提出的两种解决方案,每种方案的优缺点是什么?

eval是邪恶的。使用循环选项。

循环选项的优点在于对象是通过引用传递的。因此:

function getObjectFromString(str) {
    var parts = str.split("."), curr = window, last = parts.pop(), p;
    while( p = parts.shift()) curr = curr[p];
    return curr[last];
}

此函数返回目标对象,在您的示例中,该对象是您要查找的构造函数。

var s = "AppNamespace.SomeObject.ClassName";
var foo = new (getObjectFromString(s));

你可以做…

var obj = new ('AppNamespace.SomeObject.ClassName'
                .split('.')
                .reduce(function(object, key) {
                            return object[key];
                        }, window));

jsFiddle。

在较旧的浏览器上,可以填充reduce()

这段代码将字符串按句点(.)拆分,然后从左到右对每个字符串进行迭代,从window作为开始对象开始(如果不是,请更改它),并获取每个子属性,直到它到达最右边(在您的示例中为ClassName)。

new (...)实例化该对象。

你可以把它写成一个可重用的函数。。。

var getObjectByString = function(string, baseObject, delimiter) {
    // Only checks for string primitives, but that's OK for this example.
    if (typeof string !== 'string') {
        throw new TypeError('First argument is required and must be a string.');
    }
    baseObject = baseObject || window;
    delimiter = delimiter || '.';
    return string
            .split(delimiter)
            .reduce(function(object, key) {
                      return object[key];
                    }, baseObject));
};