浅拷贝和深拷贝

对于网上深浅拷贝的定义观点各不一致,有点误人子弟!
在此写这篇文章也是为了帮助大家更好的做区分和理解

区分

浅拷贝是指对象复制的时候只复制一层
深拷贝是指复制对象的所有层级,不共享内存(修改新对象不会改到原对象)

对象

浅拷贝

1. 通过引用赋值

const obj = { name: '张三' };
const newObj = obj; 

2. 通过Object.assign()

const obj = { name: '张三' };
const newObj = Object.assign(obj,{}); 

3. 通过…拓展运算符 (拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

const obj = { name: '张三' };
const newObj = {...obj}; 

4. for in 复制第一层(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

const obj = { name: '张三' };
const newObj = {}; 
for(let key in obj){
	newObj[key] = obj[key]
}

深拷贝

1. 通过JSON, 会造成方法丢失

const obj = { name: '张三' };
const newObj = JSON.parse(JSON.stringify(obj)); 

2. 递归;缺点:性能不好,占用内存

简易版,还有很多因素没考虑到(慎用)

    function deepClone(obj) {
    	// 数组, 对象, null通过 typeof 检测都为 object
        if ((typeof obj !== 'object') || obj === null) return obj;
        let result = new obj.constructor // 另一种方式 Array.isArray(obj) ? [] :{}
        for (let key in obj) {
            // 判断对象自身属性中是否具有指定的属性
            if (obj.hasOwnProperty(key)) {
                result[key] = deepClone(obj[key]) // 递归
            }
        }
        return result
    }

3. 通过structuredClone

需考虑浏览器兼容问题,Function和Dom节点拷贝不了

const obj = { name: '张三' };
const newObj = structuredClone(obj)

4. 使用Immutable.js

5. 使用lodash库中的_.cloneDeep方法

数组

浅拷贝

1. 通过引用赋值

const arr = [ 1, 2 ]
const newArr = arr

2. 通过slice(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

const arr = [ 1, 2 ]
const newArr = arr.slice()

3. 通过…拓展运算符(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

const arr = [ 1, 2 ]
const newArr = [...arr]

4. 通过concat(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

const arr = [ 1, 2 ]
const newArr = arr.concat()

5. 遍历复制数组 for 、while、map、 filter、 reduce(拷贝后的对象第一层中基础类型修改了是不会影响到原对象的)

深拷贝

1. 通过JSON, 会造成方法丢失

const arr = [ 1, 2 ]
const newArr = JSON.parse(JSON.stringify(arr)); 

2. 递归;缺点:性能不好,占用内存

3. 通过structuredClone

4. 使用Immutable.js

5. 使用lodash库中的_.cloneDeep方法

你可能感兴趣的:(ECMAScript,javascript,前端)