JavaScript中的浅拷贝和深拷贝?他们的区别是什么?

发布时间:2022-06-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了JavaScript中的浅拷贝和深拷贝?他们的区别是什么?脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

在了解浅拷贝和深拷贝前,需要先了解到JavaScript中的不同数据存储方式,不同数据类型的拷贝方式,也是不同的。

基本类型数据和引用数据类型

基本数据类型 String Number Boolean Null Undefined 引用数据类型 Object JS中的变量都是保存到 栈内存中的 基本数据类型的值是直接在栈内存中存储

对象是保存到 堆内存中的 每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的 内存地址(对象的引用),如果两个变量保存的是同一个对象应用,当一个通过一个变量修改属性时,另一个也会因地址指向的原因受到影响。

基本类型数据的拷贝方式

对于基本类型数据的拷贝就是一个值赋值到另一个过程中,修改其中一个值,另一个也不会受到影响。

let a = 1;
let b = a; //把a的拷贝到b
a = 3;
console.log(a); //3
console.log(b); //1

JavaScript中的浅拷贝和深拷贝?他们的区别是什么?

基本类型数据的拷贝在内存过程大概和下面图:

JavaScript中的浅拷贝和深拷贝?他们的区别是什么?

引用数据的拷贝方式

对于引用数据的拷贝,本质是拷贝了对象的储存地址,拷贝后的变量最终还是指向同一个对象,如果修改其中一个变量中的值,另一个指向对象的变量也会跟着更改。


数组的浅拷贝

let oldArray = [1,4,"木龙","刀圭","意马"];
let newArray = oldArray;//进行拷贝

oldArray[0] = "江流";//修改oldArray的值

console.log("oldArray:",oldArray);
console.log("newArray:",oldArray);

JavaScript中的浅拷贝和深拷贝?他们的区别是什么?

数组也是对象,这就是对象的一种浅拷贝方式。 引用类型数据的拷贝在内存过程大概下面图一样:

JavaScript中的浅拷贝和深拷贝?他们的区别是什么?

当我们修改oldArray[0] = "江流"的时候,因为在拷贝的时候只是将oldArray所指向的地址赋值给newArray,当通过oldArray去修改堆空间的中值时,也会导致打印newArray的值也会发生改变。这种方式就是浅拷贝。

JavaScript中的浅拷贝和深拷贝?他们的区别是什么?


对象的浅拷贝

var  oldObj = {
    name:"心猿",
    age:2000
}

var newObj = oldObj;//浅拷贝

oldObj.age = 5000;//修改年龄

console.log("oldObj:",oldObj);
console.log("newObj:",newObj);

JavaScript中的浅拷贝和深拷贝?他们的区别是什么?


浅拷贝和深拷贝的概念

浅拷贝:完成拷贝后可能存在彼此之间操作互相影响的就是浅拷贝

深拷贝:完成拷贝后彼此之间操作绝不会有互相影响的就是深拷贝

也有其他解释:浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;深拷贝是拷贝多层,每一级别的

数据都会拷贝出来


深拷贝

JSON.parse()、JSON.stringify()

语法:

var oldObj = {
    name: "心猿",
    age: 2000
}

var newObj = JSON.parse(JSON.stringify(oldObj));//浅拷贝

newObj.age = 5000;//修改年龄

console.log("oldObj:", oldObj);
console.log("newObj:", newObj);

JavaScript中的浅拷贝和深拷贝?他们的区别是什么?

粗暴简单,但是也有缺点。 缺点: 可能会影响数剧,函数无法通过这个拷贝,日期类型的数据会变成字符串。


递归

思路: 在对属性值进行拷贝的时候,先判断属性值的类型,如果是对象,就用递归调用深拷贝函数,如果不是,就直接拷贝。

function deepCopy(obj) {
    if (typeof obj[key] === 'object') return;
    if (Array.isArray(obj)) {//判断是否是数组还是对象
        var newObj = [];
    }
    else {
        var newObj = {};
    }
    for (var key in obj) {
        if (typeof obj[key] === 'object' && !(obj[key] instanceof Date)) {
            newObj[key] = deepCopy(obj[key]);//使用递归进行拷贝
        }
        else {
            newObj[key] = obj[key];
        }
    }
    return newObj
}

测试代码:

var oldObj = {
    name: "心猿",
    gender: "男",
    age: 2000,
    power: {
        skill: "七十二变"
    }
}

var newObj = deepCopy(oldObj);//调用深拷贝


//修改oldObj中的属性值不会改变newObj中的属性值

oldObj.name = "意马";
oldObj.age = 1500;
oldObj.power.skill = "化身为白龙";

console.log("oldObj:", oldObj);
console.log("newObj:", newObj);


/*----------------------深拷贝代码---------------------------------*/
function deepCopy(obj) {
    if (typeof obj[key] === 'object') return;
    if (Array.isArray(obj)) {//判断是否是数组还是对象
        var newObj = [];
    }
    else {
        var newObj = {};
    }
    for (var key in obj) {
        if (typeof obj[key] === 'object' && !(obj[key] instanceof Date)) {
            newObj[key] = deepCopy(obj[key]);//使用递归进行拷贝
        }
        else {
            newObj[key] = obj[key];
        }
    }
    return newObj
}

JavaScript中的浅拷贝和深拷贝?他们的区别是什么?

其中深拷贝代码简化

function deepCopy(obj) {
    if (typeof obj !== 'object') return;
    let result = obj instanceof Array ? [] : {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            result[key] = typeof obj[key] === 'object' 
            && !(obj[key] instanceof Date) ? deepCopy(obj[key]) : obj[key];
        }
    }
    return result;

脚本宝典总结

以上是脚本宝典为你收集整理的JavaScript中的浅拷贝和深拷贝?他们的区别是什么?全部内容,希望文章能够帮你解决JavaScript中的浅拷贝和深拷贝?他们的区别是什么?所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: