比较两个对象,并在新值为空或为null时将旧对象道具值分配给新对象道具值的函数?

时间:2019-04-22 13:40:18

标签: javascript javascript-objects

我试图确保任何现有的,非空或空值都不会被API调用中的空或空值覆盖。

例如,假设

originalReference['data']['articleTitle'] = 'Something or other';

reference['data']['articleTitle'] = '';

其中reference是从API返回的对象,originalReference是在API调用之前存在的对象(已从MySQL数据库加载)。

我想确保此函数在这些复杂对象之间循环(这两个对象应始终具有相同的长度,并具有相同的属性名称),并将旧值重新分配给新对象。

因此,在上述用例中,函数完成后,对象articleTitle中的reference将是:

reference['data']['articleTitle'] = 'Something or other';

这是我到目前为止所拥有的:

if (referenceLength == originalReferenceLength) {
    try {
        for (var prop in reference) {
            // First check for undefined or null
            if (reference[prop] != undefined) {
                if (reference[prop] != null) {
                    if (typeof reference[prop] == 'string' && reference[prop].trim() == '') {
                        // Assign original value to new object if new value is empty string
                        reference[prop] = originalReference[prop];
                    }

                    // Check if current prop in both objects is an object
                    if (typeof reference[prop] == 'object' && typeof originalReference[prop] == 'object') {
                        for (var property in reference[prop]) {
                            // Check for undefined or null value in original
                            if (originalReference[prop][property] != undefined) {
                                if (originalReference[prop][property] != null) {
                                    if (reference[prop][property] == null || reference[prop][property] == '') {
                                        // Assign old non-null value to new object if new value is empty or null
                                        reference[prop][property] = originalReference[prop][property];
                                    }
                                }
                            }
                        }
                    }

                    if (Array.isArray(reference[prop]) && typeof Array.isArray(originalReference[prop])) {
                        // Recurse if both are arrays
                        reference[prop].forEach((item, index) => vm.evaluateEmptyValues(item, originalReference[prop][index]));
                    }
                } else {
                    if (originalReference[prop] != undefined) {
                        if (originalReference[prop] != null) {
                            // Assign original value to new object
                            reference[prop] = originalReference[prop];
                        }
                    }
                }
            } else {
                if (originalReference[prop] != undefined) {
                    if (originalReference[prop] != null) {
                        // Assign original value to new object
                        reference[prop] = originalReference[prop];
                    }
                }
            }
        }
    } catch(err) {
        console.log(err);
    }
}

1 个答案:

答案 0 :(得分:0)

不要认为它有什么问题,但是可能DRYer很多,并且更可重用。

特别是作为对象本身的prop的迭代只会尖叫递归,因此可以进行重构:

function mergeNewReference(origRef, newRef, enforceSameProps=true){
  if(!newRef){
    console.log('newRef is empty, not sure what should happen')
  }else if(enforceSameProps && origRef.length != newRef.length){
     console.log('Objects have different length, not sure what should happen');
  }else{
    for(prop in newRef){
      var newVal = newRef[prop];
      if(!isNullOrUndefined(newVal)){
        var origVal = origRef[prop];
        if(isNullOrUndefined(origVal) || isEmptyString(origVal)){
          origRef[prop] = newVal;
        }else if(typeof newVal == typeof origVal && typeof newVal[Symbol.iterator] === 'function'){
          mergeNewReference(origVal, newVal, false)
        }
      }
    }
  }
  return origRef;
}

//These helper methods could be better encapsulated inside the merge method. 
//I'll leave them here for better readability
function isNullOrUndefined(val){
  return val == null || val == undefined;
}
function isEmptyString(str){
  return typeof str == 'string' && str.trim() == ''
}

注意:如果嵌套对象具有多个级别,则它将返回与算法不同的结果,因为它会进行深度合并。