如果我有对象的引用:

var test = {};

可能(但不是立即)具有嵌套对象,例如:

{level1: {level2: {level3: "level3"}}};

检查深度嵌套对象中是否存在属性的最佳方法是什么?

警报(测试级别1);生成未定义,但警告(test.level1.level2.level3);失败。

我目前正在做这样的事情:

if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
    alert(test.level1.level2.level3);
}

但我想知道是否有更好的方法。


当前回答

简单使用https://www.npmjs.com/package/js-aid用于检查嵌套对象的包。

其他回答

我已经使用这个函数来访问深度嵌套对象的财产,它对我来说很有效。。。

这是函数

/**
 * get property of object
 * @param obj object
 * @param path e.g user.name
 */
getProperty(obj, path, defaultValue = '-') {
  const value = path.split('.').reduce((o, p) => o && o[p], obj);

  return value ? value : defaultValue;
}

这是我访问深度嵌套对象属性的方式

{{ getProperty(object, 'passengerDetails.data.driverInfo.currentVehicle.vehicleType') }}

在代码库(safeRead)中有一个函数,它将以安全的方式执行此操作。。。即

safeRead(test, 'level1', 'level2', 'level3');

如果任何属性为null或未定义,则返回空字符串

今天刚刚编写了这个函数,它对嵌套对象中的属性进行了深入搜索,如果找到了,则返回该属性的值。

/**
 * Performs a deep search looking for the existence of a property in a 
 * nested object. Supports namespaced search: Passing a string with
 * a parent sub-object where the property key may exist speeds up
 * search, for instance: Say you have a nested object and you know for 
 * certain the property/literal you're looking for is within a certain
 * sub-object, you can speed the search up by passing "level2Obj.targetProp"
 * @param {object} obj Object to search
 * @param {object} key Key to search for
 * @return {*} Returns the value (if any) located at the key
 */
var getPropByKey = function( obj, key ) {
    var ret = false, ns = key.split("."),
        args = arguments,
        alen = args.length;

    // Search starting with provided namespace
    if ( ns.length > 1 ) {
        obj = (libName).getPropByKey( obj, ns[0] );
        key = ns[1];
    }

    // Look for a property in the object
    if ( key in obj ) {
        return obj[key];
    } else {
        for ( var o in obj ) {
            if ( (libName).isPlainObject( obj[o] ) ) {
                ret = (libName).getPropByKey( obj[o], key );
                if ( ret === 0 || ret === undefined || ret ) {
                    return ret;
                }
            }
        }
    }

    return false;
}

我认为这是一个轻微的改进(变成了一行):

   alert( test.level1 && test.level1.level2 && test.level1.level2.level3 )

这之所以有效,是因为&&运算符返回其计算的最终操作数(并且短路)。

另一种方式:

/**
 * This API will return particular object value from JSON Object hierarchy.
 *
 * @param jsonData : json type : JSON data from which we want to get particular object
 * @param objHierarchy : string type : Hierarchical representation of object we want to get,
 *                       For example, 'jsonData.Envelope.Body["return"].patient' OR 'jsonData.Envelope.return.patient'
 *                       Minimal Requirements : 'X.Y' required.
 * @returns evaluated value of objHierarchy from jsonData passed.
 */
function evalJSONData(jsonData, objHierarchy){
    
    if(!jsonData || !objHierarchy){
        return null;
    }
    
    if(objHierarchy.indexOf('["return"]') !== -1){
        objHierarchy = objHierarchy.replace('["return"]','.return');
    }
    
    let objArray = objHierarchy.split(".");
    if(objArray.length === 2){
        return jsonData[objArray[1]];
    }
    return evalJSONData(jsonData[objArray[1]], objHierarchy.substring(objHierarchy.indexOf(".")+1));
}