Shallow copy and deep copy How to achieve a deep copy?

1. Data type storage

Basic data types are stored in stack memory

The reference data type is stored in the heap memory, and the variable of the reference data type is a reference to the actual object in the heap memory, which is stored in the stack

2. Shallow copy

Shallow copy refers to the creation of new data that has an exact copy of the original data attribute values

If the attribute is a basic data type, the value of the basic type is copied, and if the attribute is a reference type, the memory address is copied

//封装一个函数进行浅拷贝
function shallowClone(obj) {
    //声明一个新的空对象存储拷贝后的数据
    const newObj = {}
    //遍历对象
    for(let key in obj) {
        //判断obj中是否有key属性
        if(obj.hasOwnProperty(key) ){
            //将数据克隆到新对象
            newObj[key] = obj[key]
        }
    }
    //返回值这个新对象    
    return newObj
}

hasOwnProperty(propertyName)

It is used to detect whether the property is an object's own property, if it is, it returns true, otherwise it returns false, and the parameter propertyName is the name of the property to be detected

The hasOwnProperty() method is the prototype method (also known as the instance method) of Object, which is defined on the Object.prototype object, and all Object instance objects can inherit the hasOwnProperty() method

hasOwnPorperty() will only detect the object's own properties, not the properties on the object prototype, but these properties are the own properties of the prototype object itself, so the prototype object can also use hasOwnProperty() to detect its own properties

In JavaScript, the phenomenon of shallow copying is

(1) Direct assignment of reference data types

(2)Object.assign()

Used to copy the values ​​of all enumerable properties from one or more source objects to a target object. It will return the target object

const target = {name:'张三',age:20}
const source = {sex :'男'}
const result = Object.assign(target,source)
console.log(target,target === result)//{name:'张三',age :20, sex:'男'} true

(3)Array.slice(start,end)

A selected element can be returned from an existing array, a part of a string can be extracted, and the extracted part can be returned as a new string 

The first parameter: start , must, specifies where to start selecting, if this parameter is negative, it means to start extracting from the penultimate collection element of the original array

The second parameter: end, optional. Specifies where to end the extraction. This parameter is the subscript of the end array of the array fragment. If it is not written, it will intercept all elements from start to the end of the array by default. If it is negative, it means the original array The penultimate element in the end of the extraction

Return value: Returns a new array containing elements from start (including the element) to end (excluding the element)

const obj = [
    {
        name: '张三',
        age: 20,
    },
    {
        name: '李四',
        age: 18
     }
]
const newObj = obj.slice(0)
obj[1].name = '小花'
console.log(obj, newObj)

slice only copies the address of the element

(4)Array.concat()

Connect the array, the return value is the connected array

const arr = [
    {
        name : '熊大',
        age : 20,
    },
    {
        name : '熊二',
        age : 18,
    },
    {
        name : '光头强',
        age : 18,
    },

]
const newArr = arr.concat()
newArr[1].name = '吉吉国王'
console.log(arr,newArr)

​​​​​​​

 (5) Spread operator...

const arr = [
    {
        name : '佩奇',
        age : 18
    },
    {
        name : '乔治',
        age : 20
    },
]
const newArr = [...arr]  
newArr[1].name = '小花'
console.log(arr,newArr)

 ​​​​​​​​​​​​

 3. Deep copy

Deep copy opens up a new stack. The two objects are exactly the same, but correspond to different addresses. Modifying the properties of one object will not change the properties of the other object.

Common deep copy methods are:

(1)_.cloneDeep()

const _ = require('lodash')
const obj1 = {
    a : 1,
    b : { f : { g : 1 } },
    c : [1,2,3]
}
const obj2 = _.cloneDeep(oobj1)
console.log(obj1.b.f === obj2.b.f)//false

(2).jQuery.extend()

const $ = require('jQuery')
const obj = {
    a : 1,
    b : { f : { g : 1 } },
    c : [ 1, 2, 3]
}
const obj2 = $.extend(true, {}, obj1}
consloe.log(obj1.b.f === obj2.b.f)//false
    

(3)JSON.stringify()

const obj2 = JSON.parse(JSON.stringify(obj1))

But this method will have disadvantages, undefined symbol and function will be ignored

const obj = {
    name : 'a',
    name1 : undefined,
    name2 : function() {},
    name3 : Symbol('a')
}
const obj2 = JSON.parse(JSON.stringify(obj))
console.log(obj2)//{name:'a'}

 (4) Loop recursion

const obj = {
    name : '张三',
    age : 20,
    hobby : ['吃饭','睡觉','打豆豆'],
    students :{
        name : '小明',
        age : 18,
        course : 80
    }
}
//声明一个函数
function deepClone (obj,obj2){
    //遍历这个对象
    for(let key in obj){
        //如果对象包含数组
        if(obj[key] instanceof Array) {
            //则创建一个空数组
            obj2[key] = []
            //递归函数深拷贝数组
            deepClone(obj[key],obj2[key])
        }else if (obj[key] instanceof Object){//如果对象中包含对象
            //则创建一个空对象
            obj2[key] = {}
            //递归函数深拷贝对象
            deepClone(obj[key],obj2[key])
        }else {
            //如果是值类型就直接拷贝
            obj2[key] = obj[key]
        }       
    }
}
//开始拷贝
const obj2 = {}
deepClone(obj,obj2)
console.log(obj,obj2)

 4. Difference

Shallow copy only copies the pointer of the attribute pointing to an object, not the object itself. If the copied data is modified, the original data will also be modified

Deep copy will create an identical object, the new object does not share memory with the original object, and modifying the data of the new object will not modify the original data

Guess you like

Origin blog.csdn.net/Qiemo_/article/details/124688532