给定一个JavaScript对象,

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

和字符串

"a.b"

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

var val = obj.a.b

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


当前回答

这是我的代码没有使用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

其他回答

这是其中一种情况,你问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));

这是我的实现

实现1

Object.prototype.access = function() {
    var ele = this[arguments[0]];
    if(arguments.length === 1) return ele;
    return ele.access.apply(ele, [].slice.call(arguments, 1));
}

实现2(使用数组reduce而不是slice)

Object.prototype.access = function() {
    var self = this;
    return [].reduce.call(arguments,function(prev,cur) {
        return prev[cur];
    }, self);
}

例子:

var myobj = {'a':{'b':{'c':{'d':'abcd','e':[11,22,33]}}}};

myobj.access('a','b','c'); // returns: {'d':'abcd', e:[0,1,2,3]}
myobj.a.b.access('c','d'); // returns: 'abcd'
myobj.access('a','b','c','e',0); // returns: 11

它也可以处理数组中的对象

var myobj2 = {'a': {'b':[{'c':'ab0c'},{'d':'ab1d'}]}}
myobj2.access('a','b','1','d'); // returns: 'ab1d'

我在我的项目中使用了这个代码

const getValue = (obj, arrPath) => (
  arrPath.reduce((x, y) => {
    if (y in x) return x[y]
    return {}
  }, obj)
)

用法:

const obj = { id: { user: { local: 104 } } }
const path = [ 'id', 'user', 'local' ]
getValue(obj, path) // return 104

2021

您不需要每次希望在程序中添加新功能时都拉入另一个依赖项。现代JS是非常能干的和可选的链接操作符?。现在得到了广泛的支持,使这类任务变得非常简单。

只需一行代码,我们就可以编写get,它接受一个输入对象t和字符串路径。它适用于任何嵌套级别的对象和数组

Const get = (t, path) => path.split(“。”)。Reduce ((r, k) => r?。[k], t) Const mydata = {: {b: [0, {c: {d:[“你好”、“世界 " ] } } ] } } console.log (get (mydata,“a.b.1.c.d.0”)) console.log (get (mydata,“a.b.1.c.d.1”)) console.log (get (mydata,“a.b.x.y.z”))

"hello"
"world"
undefined

几年后,我发现它可以处理范围和数组。如[b] [c] .d.etc

function getScopedObj(scope, str) {
  let obj=scope, arr;

  try {
    arr = str.split(/[\[\]\.]/) // split by [,],.
      .filter(el => el)             // filter out empty one
      .map(el => el.replace(/^['"]+|['"]+$/g, '')); // remove string quotation
    arr.forEach(el => obj = obj[el])
  } catch(e) {
    obj = undefined;
  }

  return obj;
}

window.a = {b: {c: {d: {etc: 'success'}}}}

getScopedObj(window, `a.b.c.d.etc`)             // success
getScopedObj(window, `a['b']["c"].d.etc`)       // success
getScopedObj(window, `a['INVALID']["c"].d.etc`) // undefined