js 深拷贝和浅拷贝

参考链接
https://www.jianshu.com/p/cf1e9d7e94fb

一、JS的基本数据类型

  • 基本数据类型:String,Boolean,Number,Undefined,Null;

  • 引用数据类型:Object(Array,Date,RegExp,Function);

  • 基本数据类型和引用数据类型的区别:
    1、保存位置不同:基本数据类型保存在栈内存中,引用数据类型保存在堆内存中,然后在栈内存中保存了一个对堆内存中实际对象的引用,即数据在堆内存中的地址,JS对引用数据类型的操作都是操作对象的引用而不是实际的对象,如果obj1拷贝了obj2,那么这两个引用数据类型就指向了同一个堆内存对象,具体操作是obj1将栈内存的引用地址复制了一份给obj2,因而它们共同指向了一个堆内存对象;
    为什么基本数据类型保存在栈中,而引用数据类型保存在堆中?
    1)堆比栈大,栈比堆速度快;
    2)基本数据类型比较稳定,而且相对来说占用的内存小;
    3)引用数据类型大小是动态的,而且是无限的,引用值的大小会改变,不能把它放在栈中,否则会降低变量查找的速度,因此放在变量栈空间的值是该对象存储在堆中的地址,地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响;
    4)堆内存是无序存储,可以根据引用直接获取;
    按引用访问:js不允许直接访问保存在堆内存中的对象,所以在访问一个对象时,首先得到的是这个对象在堆内存中的地址,然后再按照这个地址去获得这个对象中的值;

    ECMAScript中所有函数的参数都是按值来传递的,对于原始值,只是把变量里的值传递给参数,之后参数和这个变量互不影响,对于引用值,对象变量里面的值是这个对象在堆内存中的内存地址,因此它传递的值也就是这个内存地址,这也就是为什么函数内部对这个参数的修改会体现在外部的原因,因为它们都指向同一个对象;
    2、基本数据类型使用typeof可以返回其基本数据类型,但是NULL类型会返回object,因此null值表示一个空对象指针;引用数据类型使用typeof会返回object,此时需要使用instanceof来检测引用数据类型;

深拷贝和浅拷贝简单解释

浅拷贝和深拷贝都只针对于引用数据类型,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存;但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象;

区别:浅拷贝只复制对象的第一层属性、深拷贝可以对对象的属性进行递归复制;

在这里插入图片描述

深拷贝递归实现

 var obj = {
            num: 1,
            name: '阿七',
            msg: {
                age: 18
            },
            color: ['pink', 'red', 'blue']
        }
        var o = {};
        // 封装函数
        function deepCopy(newobj, oldobj) {
            for (var k in oldobj) {
                // 判断我们的属性值是属于那种数据类型
                // 1. 获取属性值 oldobj[k] 
                var item = oldobj[k];
                // 2.判断这个值是不是数组
                if (item instanceof Array) {
                    /*
                      如果是数组的话为在索引为这个位置的 newobj[k] 新建一个空数组
                      以上面的obj为例子 相当于 
                      newobj[3] = [];
                      deepCopy(newobj[3], [color])   (个人理解) 
                     
                    */
                    newobj[k] = [];
                    deepCopy(newobj[k], item)
                } else if (item instanceof Object) {
                    // 3.判断这个值是不是对象
                    newobj[k] = {};
                    deepCopy(newobj[k], item)
                } else {
                    // 4.属于简单数据类型
                    newobj[k] = item;
                }
            }
        }
        deepCopy(o, obj)
        console.log(obj);
        console.log(o);

浅拷贝 实现

        var obj = {
            num: 1,
            name: '阿七',
            msg: {
                age: 18
            },
            color: ['pink', 'red', 'blue']
        }
        var o = {};
        o = obj
        o.age = 20
        console.log(obj);
        console.log(o);
posted @ 2020-12-11 20:45  Muliminty  阅读(37)  评论(0)    收藏  举报