给定一个JavaScript对象,

var obj = { a: { b: '1', c: '2' } }

和字符串

"a.b"

我怎么把字符串转换成点符号呢

var val = obj.a.b

如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。


当前回答

如果希望多次解除对同一路径的引用,为每个点符号路径构建函数实际上具有迄今为止最好的性能(扩展James Wilkins在上面的评论中链接到的性能测试)。

var path = 'a.b.x';
var getter = new Function("obj", "return obj." + path + ";");
getter(obj);

Using the Function constructor has some of the same drawbacks as eval() in terms of security and worst-case performance, but IMO it's a badly underused tool for cases where you need a combination of extreme dynamism and high performance. I use this methodology to build array filter functions and call them inside an AngularJS digest loop. My profiles consistently show the array.filter() step taking less than 1ms to dereference and filter about 2000 complex objects, using dynamically-defined paths 3-4 levels deep.

当然,类似的方法也可以用于创建setter函数:

var setter = new Function("obj", "newval", "obj." + path + " = newval;");
setter(obj, "some new val");

其他回答

这是一个递归的例子。

函数重组(obj,字符串){ Var parts = string.split('.'); var newObj = obj[parts[0]]; If (parts[1]) { 部分。拼接(0,1); var newString = parts.join('.'); return recompose(newObj, newString); } 返回newObj; } var obj ={答:{' 1 ',c:‘2’,d:{答:{b:“胡说”}}}}; console.log(重组(obj, ' a.d.a.b '));/ /等等

这是其中一种情况,你问10个开发人员,你会得到10个答案。

下面是我使用动态规划的OP[简化]解决方案。

其思想是,您将传递一个希望更新的现有DTO对象。这使得该方法在具有多个输入元素的表单的情况下最有用,这些输入元素的名称属性设置为圆点(fluent)语法。

使用示例:

<input type="text" name="person.contact.firstName" />

代码片段:

const setfluent = (obj, path, value) => { If (typeof path === "string") { 返回setfluent (obj, path.split("."), value); } 如果路径。长度<= 1){ Obj [path[0]] = value; 返回obj; } Const key = path[0]; obj[key] = setfluent (obj[key] ?)Obj [key]: {}, path.slice(1), value); 返回obj; }; const origObj = { 答:{ b:“1”, c:“2” } }; setfluent (origObj, "a.b", "3"); setfluent (origObj, "a.c", "4"); console.log (JSON。stringify(origObj, null, 3));

如果你可以使用Lodash,有一个函数,它可以做到这一点:

_。(物体,路径,[defaultValue])

var val = _.get(obj, "a.b");

你可以通过点表示法获得对象成员的值,只需一行代码:

new Function('_', 'return _.' + path)(obj);

对你来说:

var obj = { a: { b: '1', c: '2' } }
var val = new Function('_', 'return _.a.b')(obj);

为了简化,你可以这样写一个函数:

function objGet(obj, path){
    return new Function('_', 'return _.' + path)(obj);
}

解释:

Function构造函数创建一个新的Function对象。在JavaScript中,每个函数实际上都是一个function对象。使用function构造函数显式创建函数的语法如下:

new Function ([arg1[, arg2[, ...argN]],] functionBody)

其中arguments(arg1到argN)必须是一个对应于有效javaScript标识符的字符串,functionBody是一个包含包含函数定义的javaScript语句的字符串。

在我们的例子中,我们利用字符串函数体来检索点表示法的对象成员。

希望能有所帮助。

我建议分割路径,迭代它,减少你拥有的对象。此建议使用对于缺失属性的默认值。

const getValue = (object, keys) => keys.split('.')。Reduce ((o, k) => (o || {})[k],对象); console.log (getValue({答:{' 1 ',c:‘2’}},' a.b ')); console.log (getValue({答:{' 1 ',c:‘2’}},' foo.bar.baz '));