如何动态获取对象的嵌套属性?

时间:2015-02-03 07:18:28

标签: javascript

我需要创建一个函数来搜索对象中的属性并返回其值。 对象可以具有任意结构,其属性嵌套在其他对象中。

我怎么能改变我的剧本?

var item = {
    id: 10,
    properties: {
        parent_id: 20,
        x: {
            y: 100
        }
    }
}

function getValue(what) {
    console.log(item[what]);

}

getValue('id');
// ok return 10

getValue('properties.parent_id')
// undefined - ISSUE here I would like to have returned 20    

4 个答案:

答案 0 :(得分:3)

您可以在getValue函数参数中提供访问这些属性的语法。例如,要访问properties.parent_id,您可以使用' properties.parent_id'。

然后getValue函数应该写成如下:

function getValue(prop) {
    if (typeof(prop) !== 'string')
        throw 'invalid input string';

    props = prop.split('.');
    var value = item[props[0]];
    for(var i = 1, l = props.length; i < l; i++) {
        value = value[props[i]];
    }
    return value;
}

示例:

getValue('properties.parent_id'); //returns 20

答案 1 :(得分:2)

您需要按顺序创建一个“路径”,即按键序列。一种方法是选择永远不会用于对象键的非通用分隔符,例如, |

element = obj;
path.split("|").forEach(function(key){
    element = element[key];
});

如果您不能从密钥中排除任何字符,则必须支持转义;例如,您可以使用,来分隔键,但允许@,表示逗号是键的一部分,而@@表示符号是键的一部分。

element = obj;
(path+",").match(/([^@,]|@.)*,/g).forEach(function(x){
    element = element[x.slice(0,-1).replace(/@(.)/g, "$1")];
});

例如,路径"1,2,x,y@,z,,w@@"可用于访问

 obj[1][2].x["y,z"][""]["w@"]

答案 2 :(得分:0)

下面的代码使得平面obj可以这样访问。

    var flatten = function(obj,into,prefix){
        into = into ||{};
        prefix = prefix || '';

        _.each(obj,function(val,key){
            if(obj.hasOwnProperty(key)){
                if(val && typeof val === 'object'){
                    flatten(val,into,prefix + key + '.');
                }else{
                    into[prefix + key] = val;
                }
            }
        });
        return into;
    };

工作的JSFiddle在这里http://jsfiddle.net/fper2d73/

完整的代码是

    var item = {
        id: 10,
        properties: {
            parent_id: 20,
            x: {
                y: 100
            }
        }
    }

    var flatten = function(obj,into,prefix){
        into = into ||{};
        prefix = prefix || '';

        _.each(obj,function(val,key){
            if(obj.hasOwnProperty(key)){
                if(val && typeof val === 'object'){
                    flatten(val,into,prefix + key + '.');
                }else{
                    into[prefix + key] = val;
                }
            }
        });
        return into;
    };


    var _item = flatten(item);

    function getValue(what) {
        console.log(_item[what]);

    }

    getValue('id');
    // returns 10

    getValue('properties.parent_id')
    // returns 20

    getValue('properties.x.y')
    //returns 100

答案 3 :(得分:0)

对于深度嵌套的对象,您可以使用递归函数来检索嵌套在父Object内的所有对象。它可以应用于具有三个或更多嵌套对象的对象文字

  var parentObj = {
     parentProp: 10,
       childObj: {
           childProp: 20,
                    grandChildObj: {
                       y: {
                          z:'lol',
                          places:['newyork','canada','dhaka']
                       }
                    }
                }
      }


var arr=[];
var container=[];
container.push(parentObj);
var count=0;

function getObjNum(obj){  //<= recursive function to retrieve all the nested objects inside parent object

      var prop=Object.getOwnPropertyNames(obj);
      for(i=0;i<prop.length;i++){
          if(typeof(obj[prop[i]])=='object'){
          if(!Array.isArray(obj[prop[i]])){
            container.push(obj[prop[i]]);
            count++;
            getObjNum(obj[prop[i]]); // recursive call to getObjNum
          }
          }

      }
}
getObjNum(parentObj); // sent the parent object to getObjNum

function getVal(str){
    var split=str.split('.');

    container.forEach(function(obj){

        if(obj.hasOwnProperty(split[split.length-1])){

        console.log(obj[split[split.length-1]]);
        }


    });
}
getVal('parentObj.parentProp');
getVal('y.z');