给定一个JavaScript对象,

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

和字符串

"a.b"

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

var val = obj.a.b

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


当前回答

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

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 '));

其他回答

这是一个递归的例子。

函数重组(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 '));/ /等等

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

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

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

使用数组缩减函数将获得/设置基于提供的路径。

我用a.b.c和a.b.2.c {a:{b:[0,1,{c:7}]}}测试了它,它既可以获取键,也可以将对象更改为设置值

function setOrGet(obj, path=[], newValue){ const l = typeof path === 'string' ? path.split('.') : path; return l.reduce((carry,item, idx)=>{ const leaf = carry[item]; // is this last item in path ? cool lets set/get value if( l.length-idx===1) { // mutate object if newValue is set; carry[item] = newValue===undefined ? leaf : newValue; // return value if its a get/object if it was a set return newValue===undefined ? leaf : obj ; } carry[item] = leaf || {}; // mutate if key not an object; return carry[item]; // return object ref: to continue reduction; }, obj) } console.log( setOrGet({a: {b:1}},'a.b') === 1 || 'Test Case: Direct read failed' ) console.log( setOrGet({a: {b:1}},'a.c',22).a.c===22 || 'Test Case: Direct set failed' ) console.log( setOrGet({a: {b:[1,2]}},'a.b.1',22).a.b[1]===22 || 'Test Case: Direct set on array failed' ) console.log( setOrGet({a: {b:{c: {e:1} }}},'a.b.c.e',22).a.b.c. e===22 || 'Test Case: deep get failed' ) // failed !. Thats your homework :) console.log( setOrGet({a: {b:{c: {e:[1,2,3,4,5]} }}},'a.b.c.e.3 ',22) )

我个人的建议。

除非没有别的办法,否则不要用这种东西!

我看到很多例子,人们用它来翻译json;你会看到locale('app。主页。欢迎')这样的函数。这太糟糕了。如果你已经在object/json中有数据;你知道路径。然后直接使用locale().app.首页示例。欢迎通过改变你的函数返回对象,你得到类型安全,自动完成,不容易出现错别字。

你可以用lodash。get

在安装(npm i lodash.get)后,像这样使用它:

const get = require('lodash.get');

const myObj = { 
    user: { 
        firstName: 'Stacky', 
        lastName: 'Overflowy',
        list: ['zero', 'one', 'two']
    }, 
    id: 123 
};

console.log(get(myObj, 'user.firstName')); // outputs Stacky
console.log(get(myObj, 'id'));             // outputs 123
console.log(get(myObj, 'user.list[1]'));   // outputs one

// You can also update values
get(myObj, 'user').firstName = 'John';

我从Ricardo Tomasi的回答中复制了以下内容,并进行了修改,以创建还不存在的子对象。它的效率有点低(更多的if和创建空对象),但应该很好。

它还允许我们做Object。Prop (obj, 'a.b', false)我们之前做不到。不幸的是,它仍然不允许我们赋值为undefined…我还不知道该怎么做。

/**
 * Object.prop()
 *
 * Allows dot-notation access to object properties for both getting and setting.
 *
 * @param {Object} obj    The object we're getting from or setting
 * @param {string} prop   The dot-notated string defining the property location
 * @param {mixed}  val    For setting only; the value to set
 */
 Object.prop = function(obj, prop, val){
   var props = prop.split('.'),
       final = props.pop(),
       p;

   for (var i = 0; i < props.length; i++) {
     p = props[i];
     if (typeof obj[p] === 'undefined') {
       // If we're setting
       if (typeof val !== 'undefined') {
         // If we're not at the end of the props, keep adding new empty objects
         if (i != props.length)
           obj[p] = {};
       }
       else
         return undefined;
     }
     obj = obj[p]
   }
   return typeof val !== "undefined" ? (obj[final] = val) : obj[final]
 }