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

在javascript中,如何动态获取对象的嵌套属性,javascript,object,Javascript,Object,如果我想要“foo”和“bee”,我可以只做arr[variable]——这很简单,函数可以做到这一点 但是如果我想得到arr.bar.bazAKAarr[bar][baz],该怎么办呢 我可以向getter函数传递什么来实现这一点(当然也可以使用相同的函数获取非嵌套属性) 我尝试了getter('bar.baz')和getter('[bar][baz]'),但都不起作用 我想我可以解析点或括号(比如这里:)。有没有更干净的方法?(当然还有评估。) 特别是因为我需要在一个循环中多次为一组数组元素

如果我想要“foo”和“bee”,我可以只做
arr[variable]
——这很简单,函数可以做到这一点

但是如果我想得到
arr.bar.baz
AKA
arr[bar][baz]
,该怎么办呢

我可以向getter函数传递什么来实现这一点(当然也可以使用相同的函数获取非嵌套属性)

我尝试了
getter('bar.baz')
getter('[bar][baz]')
,但都不起作用

我想我可以解析点或括号(比如这里:)。有没有更干净的方法?(当然还有评估。)


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

将getter函数签名改为
getter('bar','baz')
怎么样

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

function getter(variable) {
  return arr[variable];
}
函数getter(){ var v=arr; for(var i=0;i
ps.没有测试,但你知道了;)

您可以访问函数参数,在这些参数中可以传递任意数量的字符串。 我还建议使用arr作为参数,以实现更好的封装:

function getter() {
  var v = arr;
  for(var i=0; i< arguments.length; i++) {
    if(!v) return null;
    v = v[arguments[i]];
  }
  return v;
}
函数getter(){ var current=参数[0]; for(var i=1;i您可以使用基于路径字符串的深度访问功能。请注意,属性名称中不能有任何句点

function getter() {
    var current = arguments[0];
    for(var i = 1; i < arguments.length; i++) {
        if(current[arguments[i]]) {
            current = current[arguments[i]];
        } else {
            return null;
        }
    }
    return current;
}

var arr = { foo : 1, bar: { baz : 2 }, bee : 3 };
var baz = getter(arr, 'bar', 'baz');
函数getPropByString(obj,propString){ 如果(!propString) 返回obj; 变量prop,props=propString.split('.'); for(var i=0,iLen=props.length-1;i 如果访问字符串为空,则返回对象。否则,继续沿着访问路径,直到最后一个访问者。如果是ojbect,则返回最后一个
对象[accessor]
值。否则,返回undefined。

有一个函数定义用于安全地从JS对象读取嵌套属性

它允许您挖掘对象的属性。。。即

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
如果对象链的任何部分为null或未定义,则返回空字符串….

使用ES6:

safeRead(arr, 'foo', 'bar', 'baz');
同:

var arr = { foo : 1, bar: { baz : 2 }, bee : 3 };
var {foo, bar, bar: {baz}, bee} = arr;
使用lodash:


我最近开发了自己的对象方法,以获得嵌套在对象和数组之间的对象属性,而不管它有多深。它采用了单行递归方法。看看这个

Object.prototype.getNestedValue=函数(…a){
返回a.length>1?(this[a[0]!==void 0和this[a[0]]。getNestedValue(…a.slice(1)):this[a[0]];
};
var myObj={foo:1,bar:{baz:2},bee:3},
bazval=myObj.getNestedValue(“bar”、“baz”);
文件编写(bazval)为您编写一行代码:

递归方式:

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' } } }
函数getPropertyByString(对象,propString){ 让值=对象; 常量props=propString.split('.'); 对于(让索引=0;索引
上述答案仅帮助您访问嵌套对象,但您可能还希望访问对象/数组数据类型中的数据。您可以尝试此递归方法:

 function getPropertyByString(object, propString) {
  let value = object;

  const props = propString.split('.');
  for (let index = 0; index < props.length; index += 1) {
    if (props[index] === undefined) break;
    value = value[props[index]];
  }
  return value;
};

const object = {
  name: 'any_name',
  address: {
    number: 77,
    test: {
      name: 'test'
    }
  }
}

console.log(getPropertyByString(object, 'address.test.name'))
// test

p、 s.Remove.flat()获取所需的数组输出。

为什么不从链接问题中使用这种方法呢?主要是因为频繁调用函数会带来开销,而且如果有更好的方法,我想学习它。另一种方法是引用回调作为变量参数,如:getter(obj=>obj.foo.bar.baz)然后在算法内部调用它getter(variable){return variable(arr)}可以测试它是否是字符串,只需使用[]表示法或函数调用它。谢谢,这正是我要找的。它的
.set
朋友也很有用。一定要解释你的答案,以便其他人可以从中学习。@AlexH我试图让代码不言自明,但我感谢你的建议。
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' } } }
   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
 function getPropertyByString(object, propString) {
  let value = object;

  const props = propString.split('.');
  for (let index = 0; index < props.length; index += 1) {
    if (props[index] === undefined) break;
    value = value[props[index]];
  }
  return value;
};

const object = {
  name: 'any_name',
  address: {
    number: 77,
    test: {
      name: 'test'
    }
  }
}

console.log(getPropertyByString(object, 'address.test.name'))
// test
const getValue = (obj, key) => {
  const keyParts = key.split(".");
  return getValueHelper(obj, keyParts);
};

const getValueHelper = (obj, keyParts) => {
  if (keyParts.length == 0) return obj;
  let key = keyParts.shift();
  if (Array.isArray(obj[key])) {
    return obj[key].map((x) => getValueHelper(x, [...keyParts])).flat();
  }
  return getValueHelper(obj[key], [...keyParts]);
};


//Examples

let data1 = {
  a: [{ b: { c: [{ d: [{ e: 1 }] }] } }, { b: { c: [{ d: [{ e: 2 }] }] } }],
};

console.log(getValue(data1, "a.b.c.d.e"));

//Output
//[ 1, 2 ]

let data2 = {
  a:{b:1},
};

console.log(getValue(data2, "a.b"));
//Output
//1