Home  >  Article  >  Web Front-end  >  Detailed explanation on the implementation of object merging function

Detailed explanation on the implementation of object merging function

小云云
小云云Original
2018-01-26 11:54:091065browse

This article mainly brings you an implementation example based on the object merging function. The editor thinks it is quite good, so I will share it with you now and give it as a reference for everyone. Let’s follow the editor to take a look, I hope it can help everyone.

Preface

$.extend() in jQuery is a tool function that is often used, mostly used to merge parameters (objects). The specific usage will not be described here. You can pass The parameter controls whether a deep copy is used during the merging process; the new Object.assign() method in ES2015 can also merge objects, but a shallow copy is used during the merging process; this article refers to the source code of jQuery's extend method. Merge your own objects, that is, copy the properties of multiple objects to the target object. If there are the same properties, the later objects will overwrite the previous ones.

Shallow copy method to achieve object merging

A previous blog post specifically introduced the deep and shallow copies of objects and arrays. If you don’t understand, please read here. Let’s look at the implementation first and then explain

function extend() { //extend 浅拷贝实现
  var name,options,copy,
   length = arguments.length,
   i = 1,
   target = arguments[0] || {}; //取目标对象
  
 if(['object','function'].indexOf(typeof target) < 0){
  target = {};
  }
 

  for(;i<length;i++){

  options = arguments[i]

  if(options != null){ //排除空参数的情况 extend({},,)

   for(name in options){ //遍历对象 赋值

   copy = options[name];

   if (copy !== undefined) {
    target[name] = copy;
   }
   }
  }
  }

  return target 
 }

 //测试数据 
 var test1 = {
  a : 1,
  b : {
  c : 2,
  d : 3
  },
  e : [1,'a']
 },
 test2 = {
  b : {
  c : 4,
  d : 5,
  f : 6
  },
  e : [1,'a'],
  g : 7
 }

 var test = extend({},test1,test2);
 console.log(test.b.d); //5

 test2.b.d = 'x'; //修改test2
 console.log(test.b.d); // 'x' test随之修改

The idea is as follows:

1. By default, the first parameter is taken as the target object. If the first parameter is not an object data type, the assignment is empty. Object

2. Traverse the remaining parameters (source object) and copy the properties of the source object to the target object.

3. Return the target object as the merged result

In the second step, the attribute values ​​​​of the source object are not judged. All are assigned using '=', so when the source object When the attribute value is an object attribute, only the reference value is copied, which is a shallow copy. From the test results, it can be seen that the attribute values ​​of the b attribute of test and test2 use the same object and will affect each other. After knowing this, you should have an idea on how to implement deep copy during merge.

Deep copy method to implement object merging

It is necessary to determine the type of the value when copying the source object attribute value. If it is an object data type, call the extend function recursively. Then you can practice the deep copy method of object merging, and the implementation is as follows:

function extend() { //extend 深拷贝实现
  var name,options,src,copy,
   deep = false, //是否深拷贝 默认为false
   length = arguments.length,
   i = 1,
   target = arguments[0] || {};

  //如果第一个参数为boolean类型,赋值给deep
  if(typeof target == 'boolean'){
  deep = arguments[0];
  target = arguments[i] || {}; //目标对象顺延
  i++;
  }

  //如果target不是对象数据类型的话 target赋值为 {}
  if(['object','function'].indexOf(typeof target) < 0){
  target = {};
  }

  for(;i<length;i++){

  options = arguments[i];

  if(options != null){

   for(name in options){

   copy = options[name];
   src = target[name];

   if(target === copy){ //避免重复循环
    continue;
   }

   if(deep && copy && (typeof copy == 'object')){ // 类型判断

    src = Object.prototype.toString.call(copy) == '[object Array]' ? [] : {}; //区分数组和‘对象'
    target[name] = extend(deep,src,copy);
   }else {

    if (copy !== undefined) {

    target[name] = copy;
    }
   }
   }
  }
  }

  return target
 }

1. Parameter judgment, if the first parameter is a Boolean type, it is taken as the parameter deep that controls whether to deep copy, deep defaults to false; At the same time, the target element will be the second parameter

2. When copying the attribute value, you must determine the type of the deep parameter and attribute value; if deep is true and the attribute value is an object type, call the extend function recursively, otherwise directly Assignment

3. It is necessary to distinguish between arrays and 'objects' to assign different initial values ​​to the properties of the target object. If they are all {}, the attribute value of the array type copied to the target element will become {'0':xx, '1': xx...}

Conclusion

Always They are all using $.extend() directly. It is easy to use but I am not very clear about the implementation. I* may not be rigorous in the implementation, but I feel that the harvest is good.

Related recommendations:

Methods to implement object merging function

The above is the detailed content of Detailed explanation on the implementation of object merging function. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn