在javascript中如何动态获取对象的嵌套属性

Ari*_*iel 27 javascript object

var arr = { foo : 1, bar: { baz : 2 }, bee : 3 }

function getter(variable) {
  return arr[variable];
}
Run Code Online (Sandbox Code Playgroud)

如果我想要"foo"vs"bee"我可以做arr[variable]- 这很容易,而且功能就是这样.

但是,如果我想获得arr.bar.bazAKA arr[bar][baz]怎么办?

我可以传递给getter函数,让我这样做,(当然也让我使用相同的函数获得非嵌套属性).

我试过了getter('bar.baz'),getter('[bar][baz]')但那些没用.

我想我可以解析为点或括号(喜欢这里:在JavaScript中,测试性能深深嵌套在对象图?).有更干净的方式吗?(当然除了eval.)

特别是因为我需要在一个循环中为一堆数组元素多次正确地设置深度.

Rob*_*obG 39

您可以使用基于路径字符串的深度访问功能.请注意,您不能在属性名称中包含任何句点.

function getPropByString(obj, propString) {
    if (!propString)
        return obj;

    var prop, props = propString.split('.');

    for (var i = 0, iLen = props.length - 1; i < iLen; i++) {
        prop = props[i];

        var candidate = obj[prop];
        if (candidate !== undefined) {
            obj = candidate;
        } else {
            break;
        }
    }
    return obj[props[i]];
}

var obj = {foo: {bar: {baz: 'x'}}};

alert(getPropByString(obj, 'foo.bar.baz')); // x
alert(getPropByString(obj, 'foo.bar.baz.buk')); // undefined
Run Code Online (Sandbox Code Playgroud)

如果访问字符串为空,则返回该对象.否则,继续沿着访问路径前进,直到最后一个访问者.如果这是一个ojbect,则返回最后一个object[accessor]值.否则,返回undefined.


Nin*_*nja 19

使用lodash库方法将是一种更好的方法: - https://lodash.com/docs#get

var arr = { foo : 1, bar: { baz : 2 }, bee : 3 };
var {foo, bar, bar: {baz}, bee} = arr;
Run Code Online (Sandbox Code Playgroud)


小智 10

递归方式:

   function getValue(obj, path) {
        if (!path) return obj;
        const properties = path.split('.');
        return getValue(obj[properties.shift()], properties.join('.'))
    }

    const myObj = {
        foo: {
            bar: {
                value: 'good'
            }
        }
    }

    console.log(getValue(myObj, 'foo.bar.value')); // good
Run Code Online (Sandbox Code Playgroud)


小智 10

使用reduce我们可以在一行代码中获取值。

const testobj = {b:{c:'1', d:{e:'2',f:'3'}}, g:{h:'3'}}

function fetchByDotOperator(object, value) {
    return value.split('.').reduce((acc, curr) => acc[curr], object);
}
console.log(fetchByDotOperator(testobj,'b.d.e'))
Run Code Online (Sandbox Code Playgroud)


Aar*_*ian 9

如何改变的getter函数签名getter('bar', 'baz')代替

function getter() {
  var v = arr;
  for(var i=0; i< arguments.length; i++) {
    if(!v) return null;
    v = v[arguments[i]];
  }
  return v;
}
Run Code Online (Sandbox Code Playgroud)

PS.没有测试,但你明白了;)


Abd*_*ail 7

这是一个非常简单的单行代码,它允许您通过“foo.bar.baz”机制进行动态访问,

var obj = {
  foo: {
    bar: {
      baz: 'foobarbaz'
    }
  }
}
const nestedAccess = "foo.bar.baz";
console.log(nestedAccess.split('.').reduce((prev, cur) => prev[cur], obj)) //'foobarbaz'
Run Code Online (Sandbox Code Playgroud)


小智 5

为您准备的一款内衬

const mock = {
  target: {
    "prop1": {
      "prop2": {
        "prop3": "sad"
      }
    }
  },
  path: "prop1.prop2.prop3",
  newValue: "happy"
};

mock.path.split(".").reduce(
  (acc, curr, i, src) =>
    (curr === src[src.length - 1]) ? acc[src[src.length - 1]] = mock.newValue : acc[curr], mock.target);


console.log(mock.target); //? { prop1: { prop2: { prop3: 'happy' } } }
Run Code Online (Sandbox Code Playgroud)