js[浅拷贝与深拷贝]探究

  • 深拷贝和浅拷贝是js中常见的一种赋值问题,其最大的核心点就是拷贝出来的内容是否占用了新的内存。
  • 数据类型分为基本类型和引用类型,基本数据类型存在于栈内存中,每一个值都占用内存空间,引用数据类型存在于堆内存中,内容由引用地址来指向。
  • 深拷贝是复制全部内容(包括引用地址和数据),浅拷贝仅仅是复制引用地址。
    这也是出现深浅拷贝的缘故。
    注意:基本数据类型的拷贝都为深拷贝。

浅拷贝方式:
方式一:使用 ‘=’ 赋值符号
在数组、对象等引用类型中,使用=来进行赋值是属于浅拷贝的内容

方式二:Object.assign()
https://es6.ruanyifeng.com/#docs/object-methods#Object-assign

深拷贝方式:
方式一:递归复制
针对数组和对象,可以采用递归循环所有内容的方式,来进行深拷贝。

//使用递归的方式实现数组、对象的深拷贝
function deepClone(obj){
	//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //子元素如果是数组,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
} 

针对只有一层属性的数组和对象是有效的,但是针对多层次的二维或多维数组或高级对象则是无效的。

方式二:使用JSON.parse和stringify(常用)
例如:

let arr = [0,1,2];
// 这里arr2就是进行了深拷贝
let arr2 = JSON.stringify(JSON.parse(arr)); 

常规的仅用于数组或对象的深拷贝是非常不错的方式
这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。

缺点:它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。
当值为undefined、function、symbol 会在转换过程中被忽略。。。所以,对象值有这三种的话用这种方法会导致属性丢失
这种方式,只有可以转成JSON格式的对象才可以这样用

方式三:通过jQuery的extend方法实现深拷贝(需要引用jquery)

$.extend(true,[],array)

方式四:lodash函数库实现深拷贝(需要引用lodash)

lodash.cloneDeep()

你可能感兴趣的:(javascript)