我有一个这样的数据结构:

var someObject = {
    'part1' : {
        'name': 'Part 1',
        'size': '20',
        'qty' : '50'
    },
    'part2' : {
        'name': 'Part 2',
        'size': '15',
        'qty' : '60'
    },
    'part3' : [
        {
            'name': 'Part 3A',
            'size': '10',
            'qty' : '20'
        }, {
            'name': 'Part 3B',
            'size': '5',
            'qty' : '20'
        }, {
            'name': 'Part 3C',
            'size': '7.5',
            'qty' : '20'
        }
    ]
};

我想使用这些变量访问数据:

var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";

part1name应该用someObject.part1.name的值填充,即“Part 1”。part2quantity也是一样,它的容量是60。

有没有办法实现这与纯javascript或JQuery?


当前回答

这可能永远都不会曝光……但不管怎样,它在这里。

将[]括号语法替换为。 继续前进。字符 删除空白字符串 找到路径(否则未定义)

(为了找到一个对象的路径,使用这个pathTo解决方案。)

// "one liner" (ES6) const deep_value = (obj, path) => path .replace(/\[|\]\.?/g, '.') .split('.') .filter(s => s) .reduce((acc, val) => acc && acc[val], obj); // ... and that's it. var someObject = { 'part1' : { 'name': 'Part 1', 'size': '20', 'qty' : '50' }, 'part2' : { 'name': 'Part 2', 'size': '15', 'qty' : '60' }, 'part3' : [ { 'name': 'Part 3A', 'size': '10', 'qty' : '20' } // ... ], 'pa[rt3' : [ { 'name': 'Part 3A', 'size': '10', 'qty' : '20' } // ... ] }; console.log(deep_value(someObject, "part1.name")); // Part 1 console.log(deep_value(someObject, "part2.qty")); // 60 console.log(deep_value(someObject, "part3[0].name")); // Part 3A console.log(deep_value(someObject, "part3[0].....name")); // Part 3A - invalid blank paths removed console.log(deep_value(someObject, "pa[rt3[0].name")); // undefined - name does not support square brackets

其他回答

现在有一个npm模块可以做到这一点:https://github.com/erictrinh/safe-access

使用示例:

var access = require('safe-access');
access(very, 'nested.property.and.array[0]');

基于前面的回答,我创建了一个也可以处理括号的函数。但由于裂开,里面没有点。

function get(obj, str) {
  return str.split(/\.|\[/g).map(function(crumb) {
    return crumb.replace(/\]$/, '').trim().replace(/^(["'])((?:(?!\1)[^\\]|\\.)*?)\1$/, (match, quote, str) => str.replace(/\\(\\)?/g, "$1"));
  }).reduce(function(obj, prop) {
    return obj ? obj[prop] : undefined;
  }, obj);
}

数组可以代替字符串来处理嵌套对象和数组,例如:["my_field", "another_field", 0, "last_field", 10]

下面是一个基于该数组表示方式更改字段的示例。我在react.js中使用类似的东西来控制输入字段,改变嵌套结构的状态。

let state = {
        test: "test_value",
        nested: {
            level1: "level1 value"
        },
        arr: [1, 2, 3],
        nested_arr: {
            arr: ["buh", "bah", "foo"]
        }
    }

function handleChange(value, fields) {
    let update_field = state;
    for(var i = 0; i < fields.length - 1; i++){
        update_field = update_field[fields[i]];
    }
    update_field[fields[fields.length-1]] = value;
}

handleChange("update", ["test"]);
handleChange("update_nested", ["nested","level1"]);
handleChange(100, ["arr",0]);
handleChange('changed_foo', ["nested_arr", "arr", 3]);
console.log(state);

使用下划线的属性或propertyOf:

Var检验= { foo: { 酒吧:{ 记者:“你好” } } } Var字符串= 'foo.bar.baz'; / / document . write (_.propertyOf(测试)(string.split (' . '))) document . write (_.property (string.split(' . '))(测试); < script src = " https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js " > < /脚本>

祝你好运…

以防万一,有人在2017年或以后访问这个问题,并寻找一种容易记住的方法,这里有一篇关于在JavaScript中访问嵌套对象而不被迷惑的详细博客文章

无法读取未定义错误的属性“foo”

使用数组缩减访问嵌套对象

让我们以这个例子结构为例

const user = {
    id: 101,
    email: 'jack@dev.com',
    personalInfo: {
        name: 'Jack',
        address: [{
            line1: 'westwish st',
            line2: 'washmasher',
            city: 'wallas',
            state: 'WX'
        }]
    }
}

为了能够访问嵌套数组,您可以编写自己的数组reduce util。

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'address', 0, 'city']);
// this will return the city from the first address item.

还有一种出色的类型处理最小库类型可以为您完成所有这些。

使用typy,代码看起来像这样

const city = t(user, 'personalInfo.address[0].city').safeObject;

免责声明:我是这个软件包的作者。