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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6906108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:42:09  来源:igfitidea点击:

In javascript how can I dynamically get a nested property of an object

javascriptobject

提问by Ariel

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

function getter(variable) {
  return arr[variable];
}

If I want 'foo' vs 'bee' I can just do arr[variable]- that's easy, and the function does that.

如果我想要 'foo' 与 'bee',我可以这样做arr[variable]- 这很容易,而且函数就是这样做的。

But what if I want to get arr.bar.bazAKA arr[bar][baz]?

但是如果我想获得arr.bar.bazAKAarr[bar][baz]呢?

What can I pass to the getter function that will let me do that, (and of course also let me get non-nested properties using the same function).

我可以向 getter 函数传递什么来让我这样做(当然也让我使用相同的函数获取非嵌套属性)。

I tried getter('bar.baz')and getter('[bar][baz]')but those didn't work.

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

I suppose I can parse for dots or brackets (like here: In javascript, test for property deeply nested in object graph?). Is there a cleaner way? (Besides eval of course.)

我想我可以解析点或括号(就像这里:在javascript中,测试深深嵌套在对象图中的属性?)。有更干净的方法吗?(当然除了 eval。)

Especially because I need to get the deeply set properly many many times in a loop for a bunch of array elements.

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

采纳答案by Aaron Qian

How about change the getter function signature as getter('bar', 'baz')instead

如何更改 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;
}

ps. didn't test, but you get the idea ;)

附:没有测试,但你明白了;)

回答by RobG

You can use a deep access function based on a string for the path. Note that you can't have any periods in the property names.

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

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

If the access string is empty, returns the object. Otherwise, keeps going along access path until second last accessor. If that's an ojbect, returns the last object[accessor]value. Otherwise, returns undefined.

如果访问字符串为空,则返回对象。否则,继续沿着访问路径前进,直到倒数第二个访问者。如果这是一个对象,则返回最后一个object[accessor]值。否则,返回未定义。

回答by Ninja

Using ES6:

使用 ES6:

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

Same as:

与...一样:

// var foo = 1;
// var bar = {baz: 2};
// var baz = 2;
// var bee = 3;

Using lodash: https://lodash.com/docs#get

使用 lodash:https://lodash.com/docs#get

_.get(arr, 'bar.baz'); //returns 2;
_.get(arr, 'bar.baz[5].bazzz'); //returns undefined wont throw error;
_.get(arr, 'bar.baz[5].bazzz', 'defaultvalue'); // Returns defaultValue because result is undefined 

回答by Vincent Viton

A recursive way :

递归方式:

   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

回答by Redu

I have recently developed my own Object method to get an object property nested among objects and arrays regardless how deep it is. It utilizes a single line of recursive approach. Check this out.

我最近开发了自己的 Object 方法来获取嵌套在对象和数组之间的对象属性,无论它有多深。它使用单行递归方法。看一下这个。

Object.prototype.getNestedValue = function(...a) {
  return 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");

document.write(bazval);

Now let's check a deeper nested array object combo data structure

现在让我们检查一个更深层次的嵌套数组对象组合数据结构

Object.prototype.getNestedValue = function(...a) {
  return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};

var myArr = [{fox: [{turn:[857, 432]}]}, {sax: [{pana:[777, 987]}]}, {ton: [{joni:[123, 567]}]}, {piu: [{burn:[666, 37]}]}, {sia: [{foxy:[404, 696]}]}];
  
document.write(myArr.getNestedValue(3,"piu",0,"burn",1));

I believe being able to pass search parameters dynamically to existing array methods would make actions like searching, filtering or replacing of deeply nested structures much easy.

我相信能够将搜索参数动态传递给现有的数组方法将使搜索、过滤或替换深层嵌套结构等操作变得更加容易。

回答by theonelucas

A one linerfor you:

为您准备一个班轮

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' } } }

回答by Daff

You can access the functions arguments where you can pass any number of strings. I also recommend using arr as a parameter for better encapsulation:

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

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

回答by Ben

Theres a function defined on this blogto safely read nested properties from a JS object

这个博客上定义一个函数来安全地从 JS 对象中读取嵌套的属性

It allows you to mine an object for properties... ie.

它允许你挖掘一个对象的属性......即。

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

and if any part of the object chain is null or undefined it returns an empty string....

如果对象链的任何部分为空或未定义,则返回空字符串....