当前位置: 首页 > ds >正文

深浅拷贝以及函数缓存

目录

数据类型介绍

基本数据类型(Primitive Types)

引用数据类型(Reference Types)

浅拷贝

深拷贝

利用JSON的序列化和反序列化实现深拷贝

递归实现深拷贝

第三方库lodash的cloneDeep

函数缓存的概念

 实现方法


数据类型介绍

要想了解深浅拷贝,首先得知道有哪些数据类型。在Javascript中,存在两大数据类型:

基本数据类型(Primitive Types)

JavaScript的基本数据类型包括以下六种:

  • Number: 用于表示整数或浮点数。例如:423.14
  • String: 用于表示文本数据。例如:"hello"'world'
  • Boolean: 表示逻辑值,只有truefalse两种。
  • Undefined: 表示变量未定义或未赋值。例如:let a;,此时aundefined
  • Null: 表示空值,通常用于明确赋空值的情况。例如:let b = null;
  • Symbol(ES6新增):表示唯一且不可变的值,通常用于对象属性的键。例如:Symbol('id')

基本数据类型的特点是不可变,直接存储在栈内存中。

引用数据类型(Reference Types)

引用数据类型主要包括以下两种:

  • Object: 用于存储键值对或复杂数据结构。例如:{ name: "Alice", age: 25 }
  • Array: 是特殊的对象,用于存储有序数据。例如:[1, 2, 3]
  • Function: 也是对象的一种,可以被调用执行。例如:function() { return "hello"; }
  • DateRegExp等内置对象。

引用数据类型的特点是可变,数据存储在堆内存中,变量存储的是指向堆内存的地址。

在编程中,基本数据类型通常不涉及深拷贝或浅拷贝的概念。所以面试常问的深浅拷贝指的是针对引用数据的处理。

浅拷贝

仅复制对象的顶层属性,如果属性是引用类型(如数组、对象),则复制的是引用而非实际对象。因此,修改拷贝后的引用类型属性会影响原对象。

实现浅拷贝的方式有很多,举几个案例:

 
// Object.assign()
// 使用 Object.assign() 可以快速实现浅拷贝:
const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);// 展开运算符(...)
// ES6 的展开运算符也能实现浅拷贝:
const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);// 数组的浅拷贝
// 对于数组,可以使用 slice() 或 concat():
const originalArray = [1, 2, { a: 3 }];
const copyArray = originalArray.slice();

注意

引用赋值共享同一个对象,无独立性,不属于浅拷贝
浅拷贝第一层属性独立,嵌套引用类型仍共享

var a = {a:1}
var b = a

深拷贝

会递归复制对象的所有层级,包括引用类型属性,生成一个完全独立的新对象。修改深拷贝后的对象不会影响原对象。

深拷贝开辟一个新的栈,两个对象的属性完全相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另外一个

利用JSON的序列化和反序列化实现深拷贝

JSON.parse(JSON.stringify())

优点:简单易用,常见的深拷贝的方法

缺点:无法处理函数、Symbol、undefined等非 JSON 兼容类型,会丢失这些属性

const original = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(original));

递归实现深拷贝

优点:可以处理各种类型

缺点:需要手动处理循环引用等问题

function deepClone(obj) {if (obj === null || typeof obj !== 'object') {return obj;}const clone = Array.isArray(obj) ? [] : {};for (let key in obj) {if (obj.hasOwnProperty(key)) {clone[key] = deepClone(obj[key]);}}return clone;
}

第三方库lodash的cloneDeep

优点:功能完善,处理了各种边界情况

缺点:需要引入额外库

const _ = require('lodash');
const obj = {a: 1, b: {c: 2}};
const clone = _.cloneDeep(obj);

函数缓存的概念

函数缓存是一种优化技术,通过存储函数计算结果避免重复执行相同输入的计算。适用于计算成本高或输入输出稳定的场景,如递归、API调用或数学运算。

函数缓存,就是将函数运算过的结果进行缓存,本质上就是用空间(缓存存储)换时间(计算过程),常用于缓存数据计算结果和缓存对象

 实现方法

实现函数缓存主要依靠闭包、柯里化、高阶函数。详解在其他文章。

http://www.xdnf.cn/news/15562.html

相关文章:

  • Dubbo高阶难题:异步转同步调用链上全局透传参数的丢失问题
  • iOS App 安全加固全流程:静态 + 动态混淆对抗逆向攻击实录
  • iOS如何查看电池容量?理解系统限制与开发者级能耗调试方法
  • 内网环境自签名超长期HTTPS证书,并在Chrome中显示为安全证书
  • C#自定义控件
  • 【Python】基础语法
  • 单向链表、双向链表、栈、队列复习(7.14)
  • LSV负载均衡
  • Usage of standard library is restricted (arkts-limited-stdlib) <ArkTSCheck>
  • 防火墙技术概述
  • Java行为型模式---模板方法模式
  • 【html基本界面】
  • 【视频格式转换】.264格式转为mp4格式
  • 7.15 窗口函数 | 二分 | 位运算
  • 互斥锁与同步锁
  • SAP-ABAP:SAP库存管理核心增强:IF_EX_MB_DOCUMENT_BADI 深度解析
  • AI驱动编程范式革命:传统开发与智能开发的全维度对比分析
  • 【人工智能】通过 Dify 构建聊天助手
  • 【t检验】用奶茶店排队案例解释
  • LangChain 和 Dify 是什么
  • 基于51单片机的贪吃蛇游戏Protues仿真设计
  • 数据分类分级和重要数据标准解读
  • 文献查找任务及其方法
  • 当前(2024-07-14)视频插帧(VFI)方向的 SOTA 基本被三篇顶会工作占据,按“精度-速度-感知质量”三条线总结如下,供你快速定位最新范式
  • 计算机毕业设计Java轩辕购物商城管理系统 基于 SpringBoot 的轩辕电商商城管理系统 Java 轩辕购物平台管理系统设计与实现
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘collections’问题
  • 来时路,零帧起手到Oracle大师
  • 大模型安全建设:破误区、识风险、筑防线20250714
  • 体验RAG GitHub/wow-rag
  • HTML 文本格式化标签