網站搜尋

javascript - 是否有可能創建一種類型,更加動態?


可能不是正確的詞。但我想在 JavaScript 中創建一種新類型。它將具有一個簡單的屬性,即可以這樣做:

var inst = new SomeType();
inst.key1.key2 = 'something';
inst.key1.key1.key3 = 'something';

基本上,你不需要聲明一個物件字面值來進一步擴展,它會自動創建一個。

這將允許我建立複雜的結構,而不必擔心檢查要擴展的屬性是否存在。

而不是做

inst.key1 = {};

inst.key1.key2 = 'data';

人們可以只是做

inst.key1.key2 = 'data';

和那

inst.key1 = {};

將是自動的,即會在內部發生。

這確實有實際用途。特別是我有一個註冊表模式,我會用這個新類型來以更層次化的方法組織資料。

此外,我看到一個模式,在程式庫中很常見,它會測試物件字面量是否存在,如果不存在就創建一個。

這似乎是一個常見的成語。

答案#1

你想要獲得的東西可以透過 Harmony 代理(MDN)輕鬆實現。然而,這個 API 尚不穩定,所以在非關鍵的業餘代碼中使用是可以的,但不要在生產代碼中使用(還不行)。

這裡有一個非常簡單的例子:

function getFreeChain(object) {
    var handler = {
        get: function(target, name) {
            if (name in target)
                return target[name];
            var newTarget = target[name] = {};
            return new Proxy(newTarget, handler);
        }
    };
    return new Proxy(object, handler);
}

// Usage:
var obj = {};
var magicalObj = getFreeChain(obj);
magicalObj.a.b.c.d.e.g = 1;
console.log(magicalObj.a.b.c.d.e.g); // 1
console.log(obj.a.b.c.d.e.g);        // 1
obj.x.y.z = 1;                       // TypeError: obj.x is undefined

注意:我的範例是根據最新的 Proxy 規格實作的,僅受 Firefox 支援。Chrome 只支援舊版、差異相當大的 API,這可以透過在 chrome://flags/ 開啟「實驗性 JavaScript」來啟用。這個舊 API 很醜陋,實作前者需要更多行的程式碼,因此我會留給讀者作為練習。

哦,有一個名為 DirectProxies.js 的函式庫(已被 harmony-reflect 取代),它將簡單的 Proxy API 帶到 Chrome。包含這個函式庫後,之前的程式碼將可以在 Firefox 和啟用實驗功能的 Chrome 中運行:http://jsfiddle.net/PAhYL/

答案#2

因為 JavaScript 不支持運算子重載,所以可以創建一個非常醜陋的假運算子,稱為 ._。如果有人想實現 ._,請編輯答案。

http://jsfiddle.net/586Sc/

var Obj = function () {
    this.hold = {};
};

Obj.prototype._ = function (key) {
    //implement here;
    return this;
};

var obj = new Obj();

obj._('key1')._('key2')._('key3') = 'barbarella';
console.log(test);