JS实现深拷贝的三种常用方法

229 阅读2分钟

在JavaScript中,深拷贝是一种复制对象的方法,它可以创建一个与原始对象完全独立的副本。这意味着无论你如何修改或删除副本中的数据,都不会影响到原始对象。深拷贝在处理复杂数据结构,如包含嵌套对象和数组的对象时,可以保持数据的完整性。同时,深拷贝也有助于避免在复杂应用中因对象间的引用关系导致的副作用。虽然深拷贝可能会在短期内消耗更多的资源,但它有助于提高应用性能,确保数据的正确性和功能的实现。下面就让我们来了解一下JS中常用的三种深拷贝方式。

递归实现深拷贝

利用递归函数的特性,在遍历到嵌套的对象或者数组时递归调用实现深拷贝。

//递归实现深拷贝
        const obj = {
            uname: 'kun',
            age: 18,
            hobby: ['sing', 'dance', 'rap']
        }
        const o = {}
        function deepCopy(newObj, oldObj) {
            for (let key in oldObj) {
                // key 是属性名 oldObj[key]是属性值
                if (oldObj[key] instanceof Array) {
                    newObj[key] = []
                    deepCopy(newObj[key], oldObj[key])
                } else {
                    newObj[key] = oldObj[key]
                    // newObj[key] 是一个属性名 oldObj[key] 是一个属性值
                }
            }
        }
        deepCopy(o, obj)
        console.log(o)
        o.age = 20
        console.log(obj) // 没改变 深拷贝的原因

        o.hobby[0] = 'rap'
        console.log(obj) // 深拷贝之后 obj不会收到影响
    </script>

可以看到的效果是在更改新对象o时,原先的对象obj不会收到影响。由此实现了递归深拷贝。

利用lodash库实现深拷贝

不清楚如何使用lodash的小伙伴可以到其官网查看: lodash 。 这里是利用了lodash库中的cloneDeep()完成深拷贝。

<script src="./lodash.min.js"></script>
    <script>
        const obj = {
            uname: 'kun',
            age: 18,
            hobby: ['sing', 'dance', 'rap']
        }
        // 使用 _.cloneDeep 实现深拷贝
        const o = _.cloneDeep(obj)
        console.log(o)
    </script>

这种方法也是非常用易上手,直接调用库函数就行。唯一麻烦的可能是要有lodash文件。

JSON转字符串的方式实现深拷贝

如果你不想写大段的递归函数,也不想去下载或者调用loadsh库,可以试试转字符串的方式来实现深拷贝:

<script>
        const obj = {
            uname: 'kun',
            age: 18,
            hobby: ['sing', 'dance', 'rap']
        }
        /* // 把对象转换成JSON字符串
        const str = JSON.stringify(obj) 

        // 把JSON字符串转换成对象
        const newStr=JSON.parse(str)  */
        const o=JSON.parse(JSON.stringify(obj))
    </script>

可以看到,我们先把str对象通过JSON.stringify()转换成字符串,再用JSON.parse把字符串还原为对象。因为新的对象是建立在字符串转成基础上,因此通过这个方法也实现了深拷贝。