javaScript的深拷贝与浅拷贝

本文详细介绍了JavaScript中的浅拷贝和深拷贝概念,包括手写浅拷贝、使用Object.assign()和扩展运算符实现、以及深拷贝的实现方法如手写深拷贝、JSON和lodash库的_.cloneDeep函数。
摘要由CSDN通过智能技术生成

注意:只有引用数据类型才有深拷贝和浅拷贝的概念

深拷贝和浅拷贝最根本的区别在于是否真正获取了一个对象的复制实体,而不是引用

一、浅拷贝

  • 浅拷贝:仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅拷贝的对象也会发生相应的改变
  • 浅拷贝方式:手写浅拷贝、Object.assign()、拓展运算符...

1、手写浅拷贝:原始对象的一级属性不会被修改,但是二级以上会被修

        var obj = {
            name: "张三",
            age: 18,
            sex: "男",
            like: ["吃", "喝", "玩", "乐"]
        }

        function shallowCopy(obj) {
            var objNew = {};
            for (var key in obj) {
                objNew[key] = obj[key];
            }
            return objNew;
        }
        var newObj = shallowCopy(obj);
        newObj.name = "李四";  // 修改一级属性 将新对象中的张三改为李四
        console.log(obj, newObj); // 原对象不变,新对象变为李四

        newObj.like[1] = "hello";  // 修改二级属性 将“喝” 改为hello
        console.log(obj, newObj); //愿对象与新对象中的值都发生变化

2、Object.assign()实现浅拷贝

当对象只有一层时,使用Object.assign()可以实现深拷贝

        var obj = {
            name: "张三",
            age: 18,
            sex: "男",
            like: ["吃", "喝", "玩", "乐"]
        }
        var newObj = Object.assign({},obj);
        newObj.name = "李四";  // 修改一级属性 将新对象中的张三改为李四
        console.log(obj, newObj); // 原对象不变,新对象变为李四

        newObj.like[1] = "hello";  // 修改二级属性 将“喝” 改为hello
        console.log(obj, newObj); //愿对象与新对象中的值都发生变化

3、拓展运算符  展开运算符...实现浅拷贝

        var obj = {
            name: "张三",
            age: 18,
            sex: "男",
            like: ["吃", "喝", "玩", "乐"]
        }
        var newObj = {...obj };
        newObj.name = "李四";  // 修改一级属性 将新对象中的张三改为李四
        console.log(obj, newObj); // 原对象不变,新对象变为李四

        newObj.like[1] = "hello";  // 修改二级属性 将“喝” 改为hello
        console.log(obj, newObj); //愿对象与新对象中的值都发生变化

二、深拷贝

  • 深拷贝:在计算机中开辟了一块新的内存地址用于存放复制的对象
  • 浅拷贝方式:手写深拷贝、json实现深拷贝、lodash中的 _.cloneDeep函数

1、手写深拷贝

        var obj = {
            a: undefined,
            b: "hello",
            c: 20,
            d: {
                age: 18,
                arr: [1, 2, 3, 4]
            },
            e: ["hello", "world"]
        }

        var obj1 = deepClone(obj);
        obj1.d.arr[1] = "你好";
        console.log(obj, obj1); //obj1中的改变 obj中的不变 二者互不影响

        // 深拷贝封装
        function deepClone(obj) {
            var newObj = getType(obj) == "Array" ? [] : {};
            if (typeof obj !== "object") {
                return obj;
            } else {
                for (var k in obj) {
                    // console.log(obj[k]);
                    newObj[k] = typeof(obj[k]) == "object" ? deepClone(obj[k]) : obj[k];
                }
            }
            return newObj;
        }

        // 获取数据类型封装
        function getType(obj) {
            var type = typeof obj;
            if (type !== "object") {
                return type;
            } else {
                return Object.prototype.toString.call(obj).slice(8, -1);
            }
        }

2、json方法实现深拷贝

        // JSON.parse(); 将json字符串转换为js对象
        // JSON.stringify();将js对象转换为json字符串
        var obj = {
            name: "张三",
            age: 18,
            like: ["吃", "喝", "玩", "乐"]
        }
        var obj1 = JSON.parse(JSON.stringify(obj));

        obj1.like[2] = "学习";
        console.log(obj, obj1); // obj1改变 obj不变 二者互不影响

3、lodash中的 _.cloneDeep函数

    <!-- <scriprt src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js">                    </script> -->

    <script src="./lodash1.js"></script>
    <script>
        var obj = {
            a: "hi",
            b: 20,
            c: {
                name: "张三",
                arr: [1, 2, 3]
            },
            d: ["hello", "world"]
        }
        var newObj = _.cloneDeep(obj);

        newObj.c.arr[1] = "666";
        console.log(obj, newObj); //newObj改变 obj未发生变化
    </script>
npm i lodash 安装依赖
import _ from 'lodash' 导入依赖
var newObj = _.cloneDeep(obj); 使用深拷贝

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值