与AngularJS深度合并对象

Dan*_*nze 37 javascript angularjs

通常我会使用浅拷贝对象 angular.extend()

这是一个例子:

var object1 = {
  "key": "abc123def456",
  "message": {
    "subject": "Has a Question",
    "from": "example1@example.com",
    "to": "example2@example.com"
   }
};

var object2 = {
  "key": "00700916391"
};

console.log(angular.extend({}, object1, object2));
Run Code Online (Sandbox Code Playgroud)

会给我们:

{
 "key": "00700916391",
 "message": {
   "subject": "Has a Question",
   "from": "example1@example.com",
   "to": "example2@example.com"
  }
}
Run Code Online (Sandbox Code Playgroud)

但是如果我想合并对象以便子对象不会覆盖父键,那该怎么办呢?

var object1 = {
  "key": "abc123def456",
  "message": {
    "subject": "Has a Question",
    "from": "example1@example.com",
    "to": "example2@example.com"
   }
};

var object2 = {
  "key": "00700916391",              //Overwrite me
  "message": {                       //Dont overwrite me!
    "subject": "Hey what's up?",     //Overwrite me
    "something": "something new"     //Add me
   }
};

console.log(merge(object1, object2));
Run Code Online (Sandbox Code Playgroud)

会给我们:

{
 "key": "00700916391",
 "message": {
   "subject": "Hey what's up?",
   "from": "example1@example.com",
   "to": "example2@example.com",
   "something": "something new"
  }
}
Run Code Online (Sandbox Code Playgroud)
  • 是否有一个Angular函数已经进行了深度合并,我不知道?

  • 如果不是有一个本地方式在javascript递归执行此n级深度?

Ben*_*aum 39

Angular 1.4或更高版本

用途angular.merge:

不像extend(),merge()递归下降入源对象的对象属性,执行深层副本.

angular.merge(object1, object2); // merge object 2 into object 1
Run Code Online (Sandbox Code Playgroud)

较早版本的Angular:

没有理由简单的递归算法不起作用:)

假设它们都是JSON.stringify或类似的结果:

function merge(obj1,obj2){ // Our merge function
    var result = {}; // return result
    for(var i in obj1){      // for every property in obj1 
        if((i in obj2) && (typeof obj1[i] === "object") && (i !== null)){
            result[i] = merge(obj1[i],obj2[i]); // if it's an object, merge   
        }else{
           result[i] = obj1[i]; // add it to result
        }
    }
    for(i in obj2){ // add the remaining properties from object 2
        if(i in result){ //conflict
            continue;
        }
        result[i] = obj2[i];
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

这是一个工作小提琴

(注意,这里不处理数组)


Mat*_*mar 6

在Angularjs的新版本中,他们添加了将执行深层复制的合并功能.

对于旧版本,我通过从新版本的Angularjs复制合并函数的代码来创建我的自定义函数.以下是相同的代码,

function merge(dst){
  var slice = [].slice;
  var isArray = Array.isArray;
  function baseExtend(dst, objs, deep) {
    for (var i = 0, ii = objs.length; i < ii; ++i) {
      var obj = objs[i];
      if (!angular.isObject(obj) && !angular.isFunction(obj)) continue;
      var keys = Object.keys(obj);
      for (var j = 0, jj = keys.length; j < jj; j++) {
        var key = keys[j];
        var src = obj[key];
        if (deep && angular.isObject(src)) {
          if (!angular.isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
          baseExtend(dst[key], [src], true);
        } else {
          dst[key] = src;
        }
      }
    }

    return dst;
  }
  return baseExtend(dst, slice.call(arguments, 1), true);
}
Run Code Online (Sandbox Code Playgroud)

希望这会帮助那些想知道为什么angular.merge不适用于旧版本的人.