7

无论如何,无论是本机还是通过库,都可以在 Javascript 对象上使用 autovivification 吗?

IE,假设foo是一个没有属性的对象,能够做foo.bar.baz = 5而不是需要foo.bar = {}; foo.bar.baz = 5.

4

5 回答 5

6

你不能完全用你想要的语法来做。但像往常一样,在 JS 中你可以编写自己的函数:

function set (obj,keys,val) {
    for (var i=0;i<keys.length;i++) {
        var k = keys[i];
        if (typeof obj[k] == 'undefined') {
            obj[k] = {};
        }
        obj = obj[k];
    }
    obj = val;
}

所以现在你可以这样做:

// as per you example:
set(foo,['bar','baz'],5);

不用担心是否bar或被baz定义。如果您不喜欢[..]函数调用中的 ,您可以随时迭代arguments对象。

于 2012-11-23T04:38:10.433 回答
2

纯属原生,我不这么认为。undefined不可扩展或不可更改,这是我可以想象的唯一方法,无需通过函数传递它。

于 2012-11-21T18:37:24.227 回答
2

我有这样做的愿望,所以我写了一个包来处理它

% npm install autovivify
% node
> Av = require('autovivify')
> foo = new Av()
{}
> foo.bar.baz = 5
5
> foo
{ bar: { baz: 5 } }
>

它甚至会用数字下标做数组:

> foo = new Av()
> foo.bar.baz[0] = 'hum'
> foo
{ bar: { baz: [ 'hum' ] } }
于 2016-02-12T07:28:54.823 回答
0

或者,您可以使用基于 eval 的解决方案。很丑,不推荐。

function av(xpr) {

    var res = "";
    var pos = 0;
    while (true) {

        var pos = xpr.indexOf("[",pos);
        if (pos == -1) break;
        var frag = xpr.substr(0,pos);
        pos++;

        res += "if (typeof(" + frag + ") != 'object') " + frag + " = {};\n";
    } // while

    return res + xpr;
} // av()


function main() {

    var a = {};
    a["keep"] = "yep";
    eval(av('a[1][1]["xx"] = "a11xx";   '));
    eval(av('a[1][2]["xx"] = "a12xx";   '));

    console.log(a);
} // main()
于 2013-12-22T22:17:36.983 回答
0

@slebetman 的代码似乎不起作用。最后一个键不应该被分配一个空对象,而应该是val. 此代码有效:

function autoviv(obj,keys,val) {
  for (var i=0; i < keys.length; i++) {
    var k = keys[i];
    if (typeof obj[k] === 'undefined') {
      if(i === keys.length-1) {
        obj[k] = val;
        return;
      }
      obj[k] = {};
    }
    obj = obj[k];
  }
}

foo = {}
autoviv(foo,['bar','baz'],5);
console.log(foo.bar.baz);
5
于 2017-03-15T04:49:05.003 回答