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

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?


当前回答

简单的函数,允许字符串或数组路径。

function get(obj, path) {
  if(typeof path === 'string') path = path.split('.');

  if(path.length === 0) return obj;
  return get(obj[path[0]], path.slice(1));
}

const obj = {a: {b: {c: 'foo'}}};

console.log(get(obj, 'a.b.c')); //foo

OR

console.log(get(obj, ['a', 'b', 'c'])); //foo

其他回答

这个解决方案怎么样:

setJsonValue: function (json, field, val) {
  if (field !== undefined){
    try {
      eval("json." + field + " = val");
    }
    catch(e){
      ;
    }
  }  
}

这个,用来得到:

getJsonValue: function (json, field){
  var value = undefined;
  if (field !== undefined) {
    try {
      eval("value = json." + field);
    } 
    catch(e){
      ;
    }
  }
  return value;
};

可能有些人会认为它们不安全,但它们解析字符串的速度肯定要快得多。

我只是基于一些类似的代码,我已经有了,它似乎工作:

Object.byString = function(o, s) {
    s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
    s = s.replace(/^\./, '');           // strip a leading dot
    var a = s.split('.');
    for (var i = 0, n = a.length; i < n; ++i) {
        var k = a[i];
        if (k in o) {
            o = o[k];
        } else {
            return;
        }
    }
    return o;
}

用法::

Object.byString(someObj, 'part3[0].name');

在http://jsfiddle.net/alnitak/hEsys/上可以看到一个工作演示

有些人注意到,如果传递的字符串中最左边的索引与对象中正确嵌套的条目不对应,这段代码将抛出错误。这是一个有效的问题,但我认为最好在调用时使用try / catch块来解决,而不是让这个函数对于无效的索引无声地返回undefined。

你必须自己解析字符串:

function getProperty(obj, prop) {
    var parts = prop.split('.');

    if (Array.isArray(parts)) {
        var last = parts.pop(),
        l = parts.length,
        i = 1,
        current = parts[0];

        while((obj = obj[current]) && i < l) {
            current = parts[i];
            i++;
        }

        if(obj) {
            return obj[last];
        }
    } else {
        throw 'parts is not valid array';
    }
}

这要求你也用点表示法定义数组下标:

var part3name1 = "part3.0.name";

它使解析更容易。

DEMO

这里的解决方案仅用于访问深度嵌套的键。我需要一个来访问、添加、修改和删除密钥。这是我想到的:

var deepAccessObject = function(object, path_to_key, type_of_function, value){
    switch(type_of_function){
        //Add key/modify key
        case 0: 
            if(path_to_key.length === 1){
                if(value)
                    object[path_to_key[0]] = value;
                return object[path_to_key[0]];
            }else{
                if(object[path_to_key[0]])
                    return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
                else
                    object[path_to_key[0]] = {};
            }
            break;
        //delete key
        case 1:
            if(path_to_key.length === 1){
                delete object[path_to_key[0]];
                return true;
            }else{
                if(object[path_to_key[0]])
                    return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
                else
                    return false;
            }
            break;
        default:
            console.log("Wrong type of function");
    }
};

Path_to_key:数组中的路径。你可以用你的string_path.split(".")替换它。 Type_of_function: 0用于访问(不传递任何值给值),0用于添加和修改。1表示删除。

我已经看了所有其他的答案,决定在更可读的代码中添加改进:

function getObjectValByString(obj, str) {
if (typeof obj === "string") return obj;

const fields = str.split(".");

return getObjectValByString(obj[fields[0]], fields.slice(1).join("."));}

下面是一个代码片段:

let someObject = { 合作伙伴:{ id:“目标”, 人:{ 名称:“蚂蚁”, an:{名称:“ESM”}, }, }, }; 函数getObjectValByString(obj, str) { If (typeof obj === "string")返回obj; Const fields = str.split("."); 返回getObjectValByString(obj[fields[0]], fields.slice(1).join(".")); } const result = getObjectValByString(someObject, "partner.person.an.name"); console.log ({ 结果, });