6

可能不是正确的词。但我想在 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 = {};

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

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

另外,我看到了一种模式,在库中很常见,它测试对象文字的存在,如果不存在则创建一个。

这似乎是一个常见的成语。

4

2 回答 2

7

使用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/. 这个旧的 API 很丑陋,实现以前的 API 需要更多的代码行,所以我将把它作为练习留给读者。

哦,有一个名为(由Harmony-reflectDirectProxies.js取代)的库,它为 Chrome 带来了简单的代理 API。包含这个库后,前面的代码将在 Firefox 和 Chrome 中运行(启用实验):http: //jsfiddle.net/PAhYL/

于 2013-06-19T17:47:02.590 回答
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);
于 2013-06-19T21:00:40.637 回答