给定一个JavaScript对象,
var obj = { a: { b: '1', c: '2' } }
和字符串
"a.b"
我怎么把字符串转换成点符号呢
var val = obj.a.b
如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。
给定一个JavaScript对象,
var obj = { a: { b: '1', c: '2' } }
和字符串
"a.b"
我怎么把字符串转换成点符号呢
var val = obj.a.b
如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。
当前回答
注意,如果你已经在使用Lodash,你可以使用属性或获取函数:
var obj = { a: { b: '1', c: '2' } };
_.property('a.b')(obj); // => 1
_.get(obj, 'a.b'); // => 1
js也有一个属性函数,但是不支持点表示法。
其他回答
var find = function(root, path) {
var segments = path.split('.'),
cursor = root,
target;
for (var i = 0; i < segments.length; ++i) {
target = cursor[segments[i]];
if (typeof target == "undefined") return void 0;
cursor = target;
}
return cursor;
};
var obj = { a: { b: '1', c: '2' } }
find(obj, "a.b"); // 1
var set = function (root, path, value) {
var segments = path.split('.'),
cursor = root,
target;
for (var i = 0; i < segments.length - 1; ++i) {
cursor = cursor[segments[i]] || { };
}
cursor[segments[segments.length - 1]] = value;
};
set(obj, "a.k", function () { console.log("hello world"); });
find(obj, "a.k")(); // hello world
我想把这个说出来:
function propertyByPath(object, path = '') {
if (/[,(){}&|;]/.test(path)) {
throw 'forbidden characters in path';
}
return Function(
...Object.keys(window).filter(k => window[k] instanceof Window || window[k] instanceof Document),
"obj",
`return ((o) => o${!path.startsWith('[') ? '.' : ''}${path})(...arguments, obj);`)
.bind(object)(object);
}
propertyByPath({ a: { b: 'hello1' } }, "a.b"); // prints 'hello1'
propertyByPath({ a: { b: 'hello2' } }, "['a']?.b"); // returns 'hello2'
propertyByPath({ a: { b: 'hello2' } }, "a.b;console.log()"); // throws exception
上面的代码在执行路径计算和屏蔽Window和Document对象(如果执行阻止不成功的话)的同时,努力防止代码执行。
我并不是说它是100%安全的(尽管我希望看到建议可能绕过的评论)也不是有效的,但在需要路径的灵活性(可选链等)以及一些缓解措施的情况下,它可能是合适的。
使用对象扫描似乎有点过度,但您可以简单地这样做
// const objectScan = require('object-scan'); const get = (obj, p) => objectScan([p], {abort: true, rtn: 'value'})(obj); Const obj = {a: {b: '1', c: '2'}}; console.log (get (obj, ' a.b ')); // => console.log (get (obj, * . c)); // => .as-console-wrapper {max-height: 100% !重要;上图:0} < script src = " https://bundle.run/object-scan@13.7.1 " > < /脚本>
声明:我是object-scan的作者
自述中有很多更高级的例子。
这是其中一种情况,你问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");