给定一个JavaScript对象,

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

和字符串

"a.b"

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

var val = obj.a.b

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


当前回答

如果您希望将任何包含点符号键的对象转换为这些键的数组版本,可以使用此方法。


这将转换为

{
  name: 'Andy',
  brothers.0: 'Bob'
  brothers.1: 'Steve'
  brothers.2: 'Jack'
  sisters.0: 'Sally'
}

to

{
  name: 'Andy',
  brothers: ['Bob', 'Steve', 'Jack']
  sisters: ['Sally']
}

convertDotNotationToArray(objectWithDotNotation) {

    Object.entries(objectWithDotNotation).forEach(([key, val]) => {

      // Is the key of dot notation 
      if (key.includes('.')) {
        const [name, index] = key.split('.');

        // If you have not created an array version, create one 
        if (!objectWithDotNotation[name]) {
          objectWithDotNotation[name] = new Array();
        }

        // Save the value in the newly created array at the specific index 
        objectWithDotNotation[name][index] = val;
        // Delete the current dot notation key val
        delete objectWithDotNotation[key];
      }
    });

}

其他回答

如果你想把一个字符串点符号转换成一个对象,我已经做了一个方便的小助手,它可以用dotPathToObject(" a.b.c.d ")将一个值为e的字符串转换为a.b.c.d。D ", "value")返回:

  {
    "a": {
      "b": {
        "c": {
          "d": "value"
        }
      }
    }
  }

https://gist.github.com/ahallora/9731d73efb15bd3d3db647efa3389c12

其他的建议有点晦涩难懂,所以我想我应该贡献一下:

Object.prop = function(obj, prop, val){
    var props = prop.split('.')
      , final = props.pop(), p 
    while(p = props.shift()){
        if (typeof obj[p] === 'undefined')
            return undefined;
        obj = obj[p]
    }
    return val ? (obj[final] = val) : obj[final]
}

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

// get
console.log(Object.prop(obj, 'a.c')) // -> 2
// set
Object.prop(obj, 'a.c', function(){})
console.log(obj) // -> { a: { b: '1', c: [Function] } }

这是我的代码没有使用eval。这也很容易理解。

function value(obj, props) {
  if (!props) 
    return obj;
  var propsArr = props.split('.');
  var prop = propsArr.splice(0, 1);
  return value(obj[prop], propsArr.join('.'));
}

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

console.log(value(obj, 'a.d.a.b')); // Returns blah

是的,扩展基本原型通常不是一个好主意,但是,如果你把所有扩展放在一个地方,它们可能是有用的。 这是我的方法。

   Object.defineProperty(Object.prototype, "getNestedProperty", {
    value     : function (propertyName) {
        var result = this;
        var arr = propertyName.split(".");

        while (arr.length && result) {
            result = result[arr.shift()];
        }

        return result;
    },
    enumerable: false
});

现在,您将能够获得嵌套的属性,而无需导入模块与函数或复制/粘贴函数。

例子:

{a:{b:11}}.getNestedProperty('a.b'); // Returns 11

js扩展打破猫鼬在我的项目。此外,我还读到它可能会破坏jQuery。所以,永远不要用Next.js的方式:

 Object.prototype.getNestedProperty = function (propertyName) {
    var result = this;
    var arr = propertyName.split(".");

    while (arr.length && result) {
        result = result[arr.shift()];
    }

    return result;
};

如果您希望以尽可能快的方式做到这一点,同时处理与路径解析或属性解析有关的任何问题,请检查path-value。

const {resolveValue} = require('path-value');

const value = resolveValue(obj, 'a.b.c');

该库是100%的TypeScript,适用于NodeJS +所有web浏览器。它是完全可扩展的,你可以使用较低级别的resolvePath,如果你愿意,你可以用自己的方式处理错误。

const {resolvePath} = require('path-value');

const res = resolvePath(obj, 'a.b.c'); //=> low-level parsing result descriptor