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知识库 -> JS深拷贝、浅拷贝、赋值 -> 正文阅读

[JavaScript知识库]JS深拷贝、浅拷贝、赋值

前言:要理解JS对象的深浅拷贝的前提知识:需要了解JS的数据类型以及数据类型在内存中是如何存储的(栈跟堆)

1. 赋值
如图:将含有基础类型跟引用类型的obj赋值给obj1,并修改obj1里面的基础数据类型(属性name)以及引用数据类型(属性hobby),结果obj的属性值也跟着改变,这是属于赋值,不属于浅拷贝
在这里插入图片描述

2. 浅拷贝
浅拷贝与赋值最大的不同点在于浅拷贝会新创建一个对象,浅拷贝改变基础数据类型不会影响到原数据,但是改变引用数据类型就会影响到原数据(因为拷贝的是内存地址,还是指向同一个堆)

如下代码:定义一个浅拷贝函数,分别修改了obj1的基础数据类型属性name,obj的name不受影响,而改变了obj1的引用数据类型属性hobby,obj的hobby也跟着改变。

var obj = {name:'流川命',age:16,hobby:['篮球','睡觉']};
function shallowClone(obj = {}) {//默认传一个对象
    if(typeof obj != 'object' || obj == null) {//判断传的是对象还是数组,或者传的是空值,直接返回值
        return obj
    }
    let newObj;
    if(obj instanceof Array) {//这一步,确定传的是数组还是对象
        newObj = []
    } else {
        newObj = {}
    }
    for(let i in obj) {
        if(obj.hasOwnProperty(i)) {//这个判断是为了让newObj只复制传过来的对象属性,不去复制对象原型的内容
            newObj[i] = obj[i]
        }
    }

    return newObj;
}

let obj1 = shallowClone(obj);
obj1.name = '樱木花道'
obj1.hobby.push('吃饭')
console.log('obj===',obj)
console.log('obj1===',obj1)

结果如图:
在这里插入图片描述

3. 深拷贝
要将浅拷贝改成深拷贝,可以利用递归的方法,下面代码在for循环赋值的时候加了递归就可以实现(函数名改了一下,这个不重要),结果原数据的基本数据类型的属性name以及引用数据类型的属性hobby都不受影响。

var obj = {name:'流川命',age:16,hobby:['篮球','睡觉']};
function deepClone(obj = {}) {//默认传一个对象
    if(typeof obj != 'object' || obj == null) {//判断传的是对象还是数组,或者传的是空值,直接返回值
        return obj
    }
    let newObj;
    if(obj instanceof Array) {//这一步,确定传的是数组还是对象
        newObj = []
    } else {
        newObj = {}
    }
    for(let i in obj) {
        if(obj.hasOwnProperty(i)) {//这个判断是为了让newObj只复制传过来的对象属性,不去复制对象原型的内容
            newObj[i] = deepClone(obj[i])
        }
    }

    return newObj;
}

let obj1 = deepClone(obj);
obj1.name = '樱木花道'
obj1.hobby.push('吃饭')
console.log('obj===',obj)
console.log('obj1===',obj1)

结果如图:
在这里插入图片描述

4. 深拷贝的应用场景

  • 在做增删改查中的修改功能时,利用深拷贝实现编辑页面正在编辑的内容与显示页面的数据互不影响。

注意

  1. 可以巧妙的利用JSON.parse(JSON.stringify(obj))进行深拷贝,但是有弊端。原对象中如果含有Date对象,JSON.stringify()会将其变为字符串,之后并不会将其还原为日期对象。或是含有RegExp对象,JSON.stringify()会将其变为空对象,属性中含有NaN、Infinity和-Infinity,则序列化的结果会变成null,如果属性中有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失。
  2. 原生js方法slice、concat、filter、map都不是真正意义上的深拷贝,都仅只适用于一维数组。
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-22 12:15:09  更:2021-11-22 12:16:21 
 
开发: 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年5日历 -2024/5/20 21:18:01-

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