Home  >  Article  >  Web Front-end  >  Detailed explanation and examples of deep cloning objects in JavaScript

Detailed explanation and examples of deep cloning objects in JavaScript

高洛峰
高洛峰Original
2017-01-04 09:49:131035browse

JavaScript Deep Clone Object

Today when I was working on a project, there was a requirement that required the use of deep clone objects and programming on the prototype chain. So I decided to review this knowledge point on a whim and found the corresponding information on the Internet. Knowledge,

Clone an object, this term may seem fancy, but it’s actually nothing. It’s just copying an identical object.
Maybe some beginners are thinking, isn’t that simple? So easy

var obj1 = {name: 'payen'};

var obj2 = obj1;

This is not a cloned object, obj1 and obj2 are basically the same object ,

They both pointed to the same memory address space and got the same small house

This is because the object is a reference value

Speaking of reference values ​​

The only reference values ​​in JavaScript are objects

Note here that arrays are special objects and functions are also special executable objects, that is to say , they are also objects. The so-called deep clone object means that it does not want the same house. You have to make an exact copy of the house. I don’t know if you can understand what I say= ̄ω ̄=, which is also a deep clone object. The reference value needs to be copied, and the corresponding shallow clone object only needs to take the reference value. It doesn’t matter if you don’t understand it. You will understand it after reading the code.

First let’s take a look at the shallow clone object

var house = {
  name: 'payen',
  people: {
    father: true,
    mother: true
  }
}
function easyClone(obj){
  var newObj = {};
  for(var prop in obj){
    if(obj.hasOwnProperty(prop)){
      newObj[prop] = obj[prop];
    }
  }
  return newObj;
}
var newHouse = easyClone(house);

Don’t complain that I use easy. I can’t remember how to say “easy” in English (I really don’t know how I passed CET-6). There is a small performance issue about the for-in. Interested children can read my other article

This code is very simple and I won’t explain it further

Let’s take a look at the chrome console

JavaScript 深层克隆对象详解及实例

It looks great

Then let me do one thing now

Add a person to the new house

JavaScript 深层克隆对象详解及实例

It seems that this "new house" is not new. Don't be confused by the variable name. Therefore, there are reference values. , shallow cloning is not easy to use

In this case, what should we do

Since we want to get a new object, we create a new object and copy the contents inside the old object , and then copy it to a new object.

There is another question. What if there are still objects in the object?

Then continue to repeat the process of creating and adding, obviously A loop process

But there are two types of loops

Iteration

Recursion

There is no doubt that recursion is better

In the recursive loop, when the conditions that meet the termination conditions are met, we return layer by layer to end. Then we can search for the reference value layer by layer through recursion until there is no reference value.
Let’s look at the code.

var house = {
  name: 'payen',
  people: {
    father: true,
    mother: true,
    child: {
      age: 1
    }
  },
  money: [1000,2000,3000]
}
function deepClone(original, target){
  var target = target || {};// 如果target为undefined或没传参,设置空对象
  for(var prop in original){// 遍历原对象
    if(original.hasOwnProperty(prop)){// 只拷贝对象内部,不考虑原型链
      if(typeof original[prop] === 'object'){// 引用值
        if(Object.prototype.toString.call(original[prop]) === '[object Array]'){
          target[prop] = [];// 处理数组引用值
        }else{
          target[prop] = {};// 处理对象引用值
        }// 可以用三目运算符
        deepClone(original[prop],target[prop]);// 递归克隆
      }else{// 基本值
        target[prop] = original[prop];
      }  
    }
  }
  return target;
}
var newHouse = deepClone(house);

It is written above that if-else is quite suitable for using the ternary operator, but I feel it is too lengthy, and my obsessive-compulsive disorder means that it is very uncomfortable to read. In order to prove that it is really a deep clone, I specially cloned the original house It has become complicated (we do not consider deep cloning of functions, which is troublesome and of little significance). This time it is really a new house

JavaScript 深层克隆对象详解及实例

I won’t expand on it

It can be seen that the reference value of the new object has changed, but the old object has not changed

The same applies to programming on the prototype chain

var house = {
  name: 'payen',
  people: {
    father: true,
    mother: true,
    child: {
      age: 1
    }
  },
  money: [1000,2000,3000]
}
Object.prototype.cloneTo = function(obj){
  var obj = obj || {};
  for(var prop in this){
    if(this.hasOwnProperty(prop)){
      if(typeof this[prop] === 'object'){
        if(Object.prototype.toString.call(this[prop]) === '[object Array]'){
          obj[prop] = [];
        }else{
          obj[prop] = {};
        }
        this[prop].cloneTo(obj[prop]);
      }else{
        obj[prop] = this[prop];
      }
    }
  }
  return obj;
}
var newHouse = {};
house.cloneTo(newHouse);

Thanks for reading, I hope it helps everyone, thank you for your support of this site!

For more detailed explanations and examples of JavaScript deep cloning objects, please pay attention to 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