简体   繁体   中英

ES5 JavaScript: Find specific property in nested objects and return its value

I need to return the value of a specific property of nested objects with ES5 syntax. Every object can have its own structure, so the needed property can be on different levels/places. Eg -> I have three different objects and the value of property "source" is needed:

  • first_data has that property in list.details.source
  • second_data has that property in list.details.products[0]._new.source
  • third_data does not have this property, therefore it should return false

So how can I return the value of the specific property with consideration, that it can be on any position in object?

var first_data = {
    area: "South",
    code: "S265",
    info: {
        category: "enhanced",
        label: "AB | 27AS53",
        variable: "VR"
    },
    list: {
        area: "Mid",
        details: [
            {
                source: "Spain",
                totals: 12,
                products: [
                    {
                        name: "ABC",
                        brand: "Nobrand",
                        id: "111",
                        category: "Men",
                    }
                ]
            }
        ]
    },
    time: 1654775446138
};

var second_data = {
    area: "South",
    code: "S265",
    info: {
        category: "enhanced",
        label: "AB | 27AS53",
        variable: "VR"
    },
    list: {
        area: "Mid",
        details: [
            {
                products: [
                    {
                        name: "ABC",
                        brand: "Nobrand",
                        id: "111",
                        category: "Men",
                        _new: {
                            source: "Spain",
                            totals: 12
                        }
                    }
                ]
            }
        ]
    },
    time: 1654775446138
};

var third_data = {
    area: "South",
    code: "S265",
    info: {
        category: "enhanced",
        label: "AB | 27AS53",
        variable: "VR"
    },
    list: {
        area: "Mid",
        details: [
            {
                products: [
                    {
                        name: "ABC",
                        brand: "Nobrand",
                        id: "111",
                        category: "Men"
                    }
                ]
            }
        ]
    },
    time: 1654775446138
};

I first tried to solve it with ES6, so that I can rewrite it in a second step into ES5. Here is what I have so far. The first problem is that here I am getting a false, but the property exists.

var propertyExists = function (obj, key) {

  if(obj === null || obj === undefined) {
    return false;
  }
  
  for(const k of Object.keys(obj)) {
    if(k === key) {
      return obj[k]
    }
    else {
      const val = obj[k];
      
       if(typeof val === 'object') {
      
        if(propertyExists(val, key) === true) {
          return true;
        }
      }
    }
  }
  
  return false;
}

propertyExists(first_data, 'source')

Your propertyExists function didn't work because it returned the value of source but it later checked if the value is equal to true (as described by Felix Kling in a comment above ).

Here's my implementation (originally in ES6 but I used a typescript compiler with target set to ES5):

var findProp = function (obj, prop) {
    if (typeof obj != "object") {
        return false;
    }
    if (obj.hasOwnProperty(prop)) {
        return obj[prop];
    }
    for (var _i = 0, _a = Object.keys(obj); _i < _a.length; _i++) {
        var p = _a[_i];
        if (typeof obj[p] === "object") {
            var t = findProp(obj[p], prop);
            if (t) {
                return t;
            }
        }
    }
    return false;
};

Note: It might be faster to detect which object structure it is and retrieve the value because you would then know where it is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM