关于深浅拷贝二

72 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

前面知道引用类型数组对象这种如果直接利用=号赋值的话只会赋值一个指针,并不会赋值整个引用类型数据的数据地址那么如何解决这个问题。

接下来介绍几种关于深拷贝的几种方法。

1.JSON转化,JSON.stringify是将对象转化为字符串类型,而JSON.parse是将字符串类型又开辟一块新的空间转为对象,那么这样也起到了一个重新开辟空间存储数据的作用。(不能为空)

let a = { name : 'mhj'}
let b = JSON.stringify(JSON.parse(a))
b.age = 18
console.log(a)  {name: 'mhj'}
console.log(b)  {name: 'mhj', age: 18}

很明显a和b使用了不同的堆内存地址来存储数据。,

2.利用递归来封装函数判断

//深拷贝
export function deepClone(target) {
    // 定义一个变量
    let result
    // 如果当前需要深拷贝的是一个对象的话
    if (typeof target === 'object') {
                    // 如果是一个数组的话
            if (Array.isArray(target)) {
                            result = [] // 将result赋值为一个数组,并且执行遍历
                            for (let i in target) {
                                            // 递归克隆数组中的每一项
                                            result.push(deepClone(target[i]))
                            }
                            // 判断如果当前的值是null的话;直接赋值为null
            } else if (target === null) {
                            result = null
                            // 判断如果当前的值是一个RegExp对象的话,直接赋值
            } else if (target.constructor === RegExp) {
                            result = target
            } else {
                            // 否则是普通对象,直接for in循环,递归赋值对象的所有值
                            result = {}
                            for (let i in target) {
                                            result[i] = deepClone(target[i])
                            }
            }
            // 如果不是对象的话,就是基本数据类型,那么直接赋值
} else {
            result = target
    }
    // 返回最终结果
    return result
}

利用递归 对传入的类型进行判断,以此达到实现深拷贝的作用。

3.引用lodash函数库

在lodash的函数库中就有 deepclone函数。 直接引用即可使用.

在对数据进行操作处理时,特别是在对数组和对象进行循环处理的时候,如果对需要的数据赋值一个已有对象或者数组的情况下,一定要用深拷贝进行处理,不然循环操作只会在同一个数组(对象)的数据存储地址进行操作,导致数据重复赋值,出现bug。

本人是萌新小白,如果有说的不好的地方,希望大佬多多指正,感谢各位技术大牛。