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 的深拷贝与浅拷贝

1、前端基础知识,js 数据类型

从上面的图中可以看到:

基础类型:是按照?存放在栈中,占用的内存空间的大小是确定的,并由系统自动分配和自动释放。
引用类型: 是按照地址 存在堆中,将存放在栈内存中的地址赋值给接收的变量。当我们想要访问引用类型的值的时候,需要先从栈中获得对象的地址指针,然后,在通过地址指针找到堆中的所需要的数据。

2、深拷贝与浅拷贝的区别

深拷贝:主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。
浅拷贝:主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。

因此,如果在对对象进行赋值时,如果不希望共享对象,那么就要进行深拷贝。

常用的深拷贝方法:

1. JSON.parse(? ?JSON.stringify()? ?) 序列化和反序列

var obj = {
    a: '123',
    b: 234,
    c: true,
    d: null,
    e: function() {console.log('test')},
    h: new Set([4,3,null]),
    i:Symbol('fsd'),
    k: new Map([ ["name", "test"],  ["title", "Author"]  ])
}
console.log(JSON.stringify(obj)); 
// {"a":"123","b":234,"c":true,"d":null,"h":{},"k":{}}

可以看到data这个对象的属性里基本上包含了所有的数据类型,但通过JSON字符串化后,返回的值却有缺失,原因是JSON在执行字符串化的这个过程时,会先进行一个JSON格式化,获得安全的JSON值,因此如果是非安全的JSON值,就会被丢弃掉。其中undefined、function、symbol这三种类型的值就是非安全的(包括该对象的属性循环赋值该对象),所以格式化后,就被过滤掉了,而set、map这种数据格式的对象,也并没有被正确处理,而是处理成了一个空对象。

循环引用:

// 测试数据
var data = {
    name: 'foo',
    child: null,
}
data.child = data
console.log(JSON.stringify(data));

因此,在使用JSON序列化这种操作时,要避免包含循环引用和上述几种数据类型。如果在处理嵌套的对象或者属性值是另一个对象的引用时,可以通过抛出异常的方法进行

function deepCopy(obj){ 
   if(typeof obj === 'function'){   
     throw new TypeError('请传入正确的数据类型格式')
    }
    try {
        let data = JSON.stringify(obj)
        let newData = JSON.parse(data)
        return newData
     } catch(e) {
      console.log(e)
      }
}

2、Object.assign(target, source1, source2)

es6新增的方法,可用于对象合并,将源对象的所有可枚举属性,复制到目标对象上。

var obj = {
    a: '123',
    b: 234,
    c: true,
    d: null,
    e: function() {console.log('test')},
    h: new Set([4,3,null]),
    i:Symbol('fsd'),
    k: new Map([ ["name", "test"],  ["title", "Author"]  ])
}
var newData = Object.assign({},obj)
console.log(newData)

注意:

当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝
但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝

?3、?迭代递归方法

function deepCopy(data) {
      if(typeof data !== 'object' || data === null){
            throw new TypeError('传入参数不是对象')
        }
      let newData = {};
      const dataKeys = Object.keys(data);
      dataKeys.forEach(value => {
         const currentDataValue = data[value];
         // 基本数据类型的值和函数直接赋值拷贝 
         if (typeof currentDataValue !== "object" || currentDataValue === null) {
              newData[value] = currentDataValue;
          } else if (Array.isArray(currentDataValue)) {
             // 实现数组的深拷贝
            newData[value] = [...currentDataValue];
          } else if (currentDataValue instanceof Set) {
             // 实现set数据的深拷贝
             newData[value] = new Set([...currentDataValue]);
          } else if (currentDataValue instanceof Map) {
             // 实现map数据的深拷贝
             newData[value] = new Map([...currentDataValue]);
          } else { 
             // 普通对象则递归赋值
             newData[value] = deepCopy(currentDataValue);
          } 
       }); 
      return newData;
  }

4、通过jQuery的extend方法实现深拷贝

var obj = {
    a: '123',
    b: 234,
    c: true,
    d: null,
    e: function() {console.log('test')},
    h: new Set([4,3,null]),
    i:Symbol('fsd'),
    k: new Map([ ["name", "test"],  ["title", "Author"]  ])
}
console.log($.extend(true, {}, obj))

?5、lodash函数库实现深拷贝

let clone = cloneDeep(obj)

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:23:13  更:2022-03-12 17:24:42 
 
开发: 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 7:23:33-

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