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