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

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?


当前回答

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

使用示例:

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

其他回答

而不是尝试模拟JS语法,你将不得不花费大量的计算解析,或者只是错误/忘记一些事情,比如一堆这些答案(带.s的键,有人吗?),只是使用一个键数组。

var part1name     = Object.get(someObject, ['part1', 'name']);
var part2quantity = Object.get(someObject, ['part2', 'qty']);
var part3name1    = Object.get(someObject, ['part3', 0, 'name']);

如果您需要使用单个字符串,只需JSONify它。 此方法的另一个改进是您可以删除/设置根级对象。

function resolve(obj, path) {
    let root = obj = [obj];
    path = [0, ...path];
    while (path.length > 1)
        obj = obj[path.shift()];
    return [obj, path[0], root];
}
Object.get = (obj, path) => {
    let [parent, key] = resolve(obj, path);
    return parent[key];
};
Object.del = (obj, path) => {
    let [parent, key, root] = resolve(obj, path);
    delete parent[key];
    return root[0];
};
Object.set = (obj, path, value) => {
    let [parent, key, root] = resolve(obj, path);
    parent[key] = value;
    return root[0];
};

其他功能演示:

对于.set(/.del()的bob =是不必要的,除非你的路径可能是空的(操作根对象)。 我证明我不克隆的对象使用史蒂夫保持原始的引用和检查bob == steve //true后,第一个.set(

我还没有找到一个包来使用字符串路径执行所有操作,所以我最终编写了自己的快速小包,它支持insert(), get()(默认返回),set()和remove()操作。

您可以使用点表示法、括号、数字索引、字符串数字属性以及非单词字符的键。简单用法如下:

> var jsocrud = require('jsocrud');

...

// Get (Read) ---
> var obj = {
>     foo: [
>         {
>             'key w/ non-word chars': 'bar'
>         }
>     ]
> };
undefined

> jsocrud.get(obj, '.foo[0]["key w/ non-word chars"]');
'bar'

https://www.npmjs.com/package/jsocrud

https://github.com/vertical-knowledge/jsocrud

使用下划线的属性或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 " > < /脚本>

祝你好运…

使用对象扫描,这就变成了一行。然而,更重要的是,这个解决方案考虑性能:

在搜索期间遍历一次输入(即使查询了多个键) 解析只在init上发生一次(如果查询多个对象) 允许使用*进行扩展语法

// const objectScan = require('object-scan'); const 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' }] }; const get = (haystack, needle) => objectScan([needle], { rtn: 'value', abort: true })(haystack); console.log(get(someObject, 'part1.name')); // => Part 1 console.log(get(someObject, 'part2.qty')); // => 60 console.log(get(someObject, 'part3[0].name')); // => Part 3A const getAll = (haystack, ...needles) => objectScan(needles, { reverse: false, rtn: 'entry', joined: true })(haystack); console.log(getAll(someObject, 'part1.name', 'part2.qty', 'part3[0].name')); /* => [ [ 'part1.name', 'Part 1' ], [ 'part2.qty', '60' ], [ 'part3[0].name', 'Part 3A' ] ] */ console.log(getAll(someObject, 'part1.*')); /* => [ [ 'part1.name', 'Part 1' ], [ 'part1.size', '20' ], [ 'part1.qty', '50' ] ] */ .as-console-wrapper {max-height: 100% !important; top: 0} <script src="https://bundle.run/object-scan@13.8.0"></script>

声明:我是object-scan的作者

根据阿尔尼塔克的回答。

我把填充材料包在格子里,将函数简化为单链还原。

如果对象。byPath === undefined) { 对象。byPath = (obj, path) =>路径 .replace (/ \ [(\ w +) \] / g, 1美元。) .replace(/ ^ \。/”) .split (/ \ / g)。 .reduce((ref, key) => key in ref ?Ref [key]: Ref, obj) } Const data = { foo: { 酒吧:[{ 记者:1 }) } } console.log(对象。小路(数据,foo.bar [0] .baz '))