深拷贝和浅拷贝

拷贝:所谓拷贝,就是赋值。把一个变量赋给另外一个变量,就是把变量的内容进行拷贝。把一个对象的值赋给另外一个对象,就是把一个对象拷贝一份。

浅拷贝:复制出的这个结果数据,如果发生变化,会影响原数据。

下面为大家罗列出集中常见的浅拷贝例子

浅拷贝:直接复制

        var arr1=[1,2,3,4]
        const newArr=arr1
        newArr[0]=520
        console.log(arr1)
        console.log(newArr)

 

浅拷贝:concat() 方法用于连接两个或多个数组。

    let arr = [{name:'张三'},1,2,3,4];
    let newArr = [].concat(arr);
    newArr[0].name = '李四';
    console.log(arr)
    console.log(newArr)

 

 浅拷贝:slice(数组中截取的一种方法)

            let arr = [{name:'张三'},1,2,3,4];
            let newArr = arr.slice(0);
            newArr[0].name = '李四';
            console.log(arr)
            console.log(newArr)

 浅拷贝:ES6扩展运算符

            let arr = [{name:'张三'},1,2,3,4];

            let newArr = [...arr];

            newArr[0].name = '王五';

            console.log(arr)

            console.log(newArr)

浅拷贝:使用 assign 方法创建对象 (assign 对象的合并)

            const school = {
                name: "张三",
                pos: ['北京','上海','深圳']
            }
            const newSchool = Object.assign({}, school);
            newSchool.pos[0] = 'beijing';
            console.log(school);
            console.log(newSchool);

 

深拷贝:复制出的这个结果数据,对他进行任何操作,跟原数据不会发生任何影响。(完全独立新的数据产生)

深拷贝(JSON)实现

       //JSON 实现深拷贝
        // stringify 将 JS 对象转化为 JSON 格式的字符串
        // parse    将 JSON 格式的字符串转化为 JS 对象
        //缺陷: 不能复制方法
        const school = {
            name: '许昌学院',
            pos: '河南许昌',
            study() {
                console.log('学习')
            }
        }
        //将对象转化为JSON字符串
        let str = JSON.stringify(school)
        // 将JSON字符串转换为jS对象
        let newSchool = JSON.parse(str)
        newSchool.pos = 'henanxuchang'
        console.log(school)
        console.log(newSchool)

 

深拷贝:递归实现深拷贝的思路

      const school = {
            name: '许昌学院',
            pos: ['北京','上海','深圳'],
            founder: 
            {
                name: '前端'
            },
            change: function(){
                console.log('改变');
            }
        }
        //创建数据容器
        const newSchool = {};
        //name
        newSchool.name = school.name;
        //pos
        newSchool.pos = school.pos;
        newSchool.pos = [];
        newSchool.pos[0] = school.pos[0];
        newSchool.pos[1] = school.pos[1];
        newSchool.pos[2] = school.pos[2];
        //founder
        newSchool.founder = {};
        newSchool.founder.name = school.founder.name;
        //方法:通过bind改变this指向,并把新函数赋值给newSchool.change
        newSchool.change = school.change.bind(newSchool);
        newSchool.pos[0] = 'beijing';
        console.log(school);
        console.log(newSchool);

深拷贝:封装一个深拷贝函数

            //封装一个函数
            function deepClone(data){
            //创建一个容器  typeof
            let container;
            //判断
            let type = getDataType(data);// Object Array
            //如果是对象类型,让container为一个空对象
            if(type === 'Object'){
                container = {};
            }
            //如果是数组类型,让container为一个新数组
            if(type === 'Array'){
                container = [];
            }
            //遍历数据  for...in
            for(let i in data){
                //获取键值的类型
                let type = getDataType(data[i]);// Array
                if(type === 'Array' || type==='Object'){
                    // 递归调用 deepClone 即可
                   container[i] = deepClone(data[i]);

                }else{
                    //如果键值为非引用类型数据  则『直接复制』
                    container[i] = data[i];
                }
            }
            //container
            return container;
        }       
        //待克隆的数据
        const school = {
            name: '许昌',
            pos: ['北京','上海','深圳'],
            founder: {
                name: '前端'
            },
            change: function(){
                console.log('改变');
            }
        }
        //调用函数完成深拷贝
        const newSchool = deepClone(school);
        newSchool.pos[0] = 'beijing';
        console.log(school);
        console.log(newSchool);
        
        //封装一个函数 用来获取数据的类型
        function getDataType(data){
            //判断基本数据类型,并截取
            return Object.prototype.toString.call(data).slice(8, -1);
        }

好了,如果能独立的封装出一个深拷贝的函数的话,以后想要拷贝出一个一模一样的数据直接去调用这个函数就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值