是否有可能创建一个更具动态性的新类型?

时间:2013-06-19 17:19:40

标签: 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 = {};

将是自动的,即在内部发生。

这确实有实际意义。特别是我有一个注册表模式,我将使用这种新类型来使用更分层的方法来组织数据。

另外,我看到一个在库中常见的模式,用于测试对象文字的存在,然后在不存在的情况下创建一个模式。

这似乎是一种常见的习语。

2 个答案:

答案 0 :(得分:7)

使用Harmony proxiesMDN)可以轻松实现您想要获得的内容。 但是,此API尚不稳定,因此可以在非关键业余爱好代码中使用它,但不要在生产代码中使用它。(/ p>

这是一个非常简单的例子:

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仅支持old, significantly different version of the API,可以通过启用chrome://flags/处的“实验性JavaScript”来启用。这个旧的API很难看,实现前面的API需要更多的代码行,所以我将把它作为练习留给读者。

哦,有一个名为DirectProxies.js的库(被harmony-reflect取代),它将简单的代理API引入Chrome。包含此库后,之前的代码将在Firefox和Chrome中运行(已启用实验):http://jsfiddle.net/PAhYL/

答案 1 :(得分:0)

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