IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 理解JavaScript中的深拷贝与浅拷贝 -> 正文阅读

[JavaScript知识库]理解JavaScript中的深拷贝与浅拷贝

一、基本类型与引用类型的区别

1、基本类型与引用类型在存储上的区别

现在只看栈区和堆区,也假定只是局部变量。
在这里插入图片描述

函数test()被调用时:
1、定义局部变量age,由于age是局部变量,所以在栈中申请内存空间,起名age,给age赋值为25,为基本类型,所以值直接存储在栈中。
2、定义局部变量arr,arr是局部变量,在栈中申请空间,但是由于给arr赋的值不是基本类型,而是引用类型(new出来的),所以需要先在堆中申请空间存放数据18,23,99,再把堆中的地址赋给arr,所以在栈中arr里存方法的是指向堆区的指针。

2、基本类型和引用类型

  • 基本类型:就是值类型,即在变量所对应的内存区域存储的是值,如:上面的age变量内存存储的就是值25。
  • 引用类型:就是地址类型,存放指向堆中的指针。上面的arr就是引用类型,arr对应的内存中存储着地址,真正的数据存储在地址对应的内存区域里。

二、基本类型和引用类型在赋值时内存的变化

可以理解为,赋值就是在拷贝。

1、基本类型

在这里插入图片描述

2、引用类型

在这里插入图片描述
此时,如果在声明一个arr1 = arr,将arr[0]的值修改后,arr1[0]的值也会发生变化。
在这里插入图片描述
内存会发生如下变化:
在这里插入图片描述
arr和arr1指向的是相同的内存地址。

三、深拷贝和浅拷贝

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

1、基本类型没有问题

因为基本数据类型赋值时,赋的是数据(所以不存在深拷贝和浅拷贝的问题)。

// 例如:
var x = 100;
var y = x;  // 此时x和y都是100,如果改变y的值,x的值不会改变。

2、引用类型有问题

引用类型赋值时,赋的值是地址(就是引用类型变量在栈内存中保存的内容)。

// 例如:
var arr = new Array(18, 23, 99);
var arr1 = arr; // 这就是一个简单的浅拷贝

如果改变arr1[0] = 33时,arr[0]的值也是33(上面已经测试过了)。原因就是arr和arr1引用了同一块内存区域。这是最简单的浅拷贝,只是把arr的地址拷贝了一份给arr1,并没有把arr的数据也拷贝一份,拷贝的深度不够

3、用json对象的方式来演示深拷贝和浅拷贝

(1)定义一个json对象(对象的属性也是对象)

var obj = {
	id: "909",
	name: "小王",
	color: new Array("blue", "pink", "yellow") // 引用类型
}

(2)把obj对象复制一份

  • (一)浅拷贝
var obj1 = {};
for(let key in obj) {
	obj1[key] = obj[key];
}
obj1.color[0] = "green";
console.log(obj);
console.log(obj1);

在这里插入图片描述
内存:
原始obj对象:
在这里插入图片描述
浅拷贝:
在这里插入图片描述

  • (二)深拷贝(初步)
var obj = {
	id: "909",
	name: "小王",
	color: new Array("blue", "pink", "yellow") // 引用类型
}
var obj1 = {};
for(let key in obj) {
    if(typeof obj[key] == 'object') {
        obj1[key] = [];
        for(let i in obj[key]) {
            obj1[key][i] = obj[key][i];
        }
    } else {
        obj1[key] = obj[key];
    }
}
obj1.color[1] = "black";
console.log(obj);
console.log(obj1);

在这里插入图片描述
内存:
在这里插入图片描述

  • (三)深拷贝(最终)

3.1 如果属性都是json对象,那么采用递归的方式

var p = {
    "id": "007",
    "name": "Sean",
    "wife": {
        "id": "008",
        "name": "Yibo",
        "address": {
            "city": "beijing",
            "area": "海淀区"
        }
    }
}
function copyDeep(obj) {
    let newObj = {};
    for(let key in obj) {
        if(typeof obj[key] == 'object') { // 如果是引用类型,就递归
            newObj[key] = copyDeep(obj[key]);
        } else { // 基本类型,则直接赋值
            newObj[key] = obj[key];
        }
    }
    return newObj;
}
let newP = copyDeep(p);
newP.wife.name = "bobo";
newP.wife.address.city = "shanghai";
console.log(newP);
console.log(p);

在这里插入图片描述

3.2 如果属性是数组等非键值对的对象

// 给数组对象增加一个方法,用来复制自己
Array.prototype.copyself = function() {
    let arr = new Array();
    for(let i in this) {
        arr[i] = this[i];
    }
    return arr;
}
var aObj = {
    id: "111",
    name: "Sean",
    like: new Array("apple", "banana", "lemon")
}
function copyObj(obj) {
    let newObj = {};
    for(let key in obj) {
        if(typeof obj[key] == 'object') {
            newObj[key] = obj[key].copyself();
        } else {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}
var newVal = copyObj(aObj);
newVal.like[0] = "orange";
console.log(aObj);
console.log(newVal);

在这里插入图片描述
参考链接:https://blog.csdn.net/jiang7701037/article/details/98738487

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:32:12  更:2022-04-18 17:33:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:36:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码