动态设置嵌套对象的属性

新手上路,请多包涵

我有一个对象,它的深度可以是任意数量的,并且可以具有任何现有属性。例如:

 var obj = {
    db: {
        mongodb: {
            host: 'localhost'
        }
    }
};

我想像这样设置(或覆盖)属性:

 set('db.mongodb.user', 'root');
// or:
set('foo.bar', 'baz');

属性字符串可以有任何深度,值可以是任何类型/事物。

如果属性键已经存在,则不需要合并作为值的对象和数组。

前面的例子会产生以下对象:

 var obj = {
    db: {
        mongodb: {
            host: 'localhost',
            user: 'root'
        }
    },
    foo: {
        bar: baz
    }
};

我怎样才能实现这样的功能?

原文由 John B. 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 517
2 个回答

此函数使用您指定的参数,应添加/更新 obj 容器中的数据。请注意,您需要跟踪 obj 架构中的哪些元素是容器,哪些是值(字符串、整数等),否则您将开始抛出异常。

 obj = {};  // global object

function set(path, value) {
    var schema = obj;  // a moving reference to internal objects within obj
    var pList = path.split('.');
    var len = pList.length;
    for(var i = 0; i < len-1; i++) {
        var elem = pList[i];
        if( !schema[elem] ) schema[elem] = {}
        schema = schema[elem];
    }

    schema[pList[len-1]] = value;
}

set('mongo.db.user', 'root');

原文由 bpmason1 发布,翻译遵循 CC BY-SA 3.0 许可协议

Lodash 有一个 _.set() 方法。

 _.set(obj, 'db.mongodb.user', 'root');
_.set(obj, 'foo.bar', 'baz');

原文由 aheuermann 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题