簡體   English   中英

為 JavaScript 中的命名空間字符串表示獲取構造函數 function 的最佳方法

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

如果我有諸如"AppNamespace.SomeObject.ClassName"之類的字符串,並且我知道該字符串表示實際構造函數 function,那么在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是邪惡的。 使用循環選項。

loop 選項的好處是對象通過引用傳遞。 所以:

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

這個 function 返回目標 object,在您的示例中它是您正在尋找的構造函數。

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));

js小提琴

在舊版瀏覽器上,您可以使用 shim reduce()

此代碼按句點 ( . ) 拆分字符串,然后從左到右遍歷每個字符串,以window作為開頭 object(如果不是則更改它)並獲取每個子屬性,直到它到達最右邊(您的示例中的ClassName )。

new (...)實例化了這個 object。

你可以把它寫成一個可重復使用的 function...

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));
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM