当前位置:网站首页>详解深拷贝,浅拷贝
详解深拷贝,浅拷贝
2022-08-07 06:40:00 【dancria】
目的:深拷贝希望赋值后的变量的变化不会影响到原来的变量
基础知识要求:
数据类型
基本数据类型:number,string ,boolean,null,undefined,bigInt,symbol
复杂(引用、Object类型)数据类型:object,arry,date,function,regexp
基本数据类型存储在栈中,复杂数据类型存储在堆中,在栈中只保留复杂数据类型的属性和引用地址
判断数据类型的方法
- typeof
- 使用方法:
- typeof 10 //‘Number’
- typeof {}//‘Object’
- typeof null//‘Object’

- 缺点:typeof null的值为object,无法分辨是null还是object
- 使用方法:
- instanceof
- 使用方法:
- function instanceof func;//true
- 123 instanceof Number;//false;
- 缺点:只能判断对象是否存在目标对象的原型链上,不能判断字面量的基本数据类型
- 使用方法:
原型链中的任何属性都会产生值,如何处理到不需要的属性
- 让你的程序做检查,并丢弃值为函数的属性
- 使用hasOwnProperty方法。如果对象拥有独有的属性,它将会返回true。hasOwnProperty方法不会检查原型链()。
浅拷贝:复杂数据类型的存在赋值关系的两个变量指向同一个引用地址
深拷贝:旧对象指向原来的引用地址,新对象在堆中创建一个新的空间,指向新的引用地址
浅拷贝原理:
参考B站up“前端小野森森-2”
浅拷贝方式1
const oldObj={
name:'哈默',
age:20,
colors:['orange','green','blue'],
friend:{
name:'小夏'
},
}
const newObj=oldObj;
newObj.name='小野';
console.log('oldObj',oldObj);
console.log('newObj',newObj);
解析:oldObj.name和newObj.name的值是一样的,因为是浅拷贝,我们改变了对象的一个值,另一个对象对应的值也会跟着改变;
当我们不希望出现同步改变的时候,就会用到深拷贝;
即newObj的值发生改变时,oldObj的值不会改变
const oldObj={
name:'哈默',
age:20,
colors:['orange','green','blue'],
friend:{
name:'小夏'
},
}
function deepClone(obj){
if( typeof obj !=='object'||obj == null){
return obj;}
let result;
if(obj instanceof Array){
result= [];
}else{
result={};
};
for(let key in obj){
result[key]=obj[key]
};
return result;
}
const newObj=deepClone(oldObj);
newObj.name='小野';
console.log('oldObj',oldObj);
console.log('newObj',newObj);
但是这种方式的深拷贝,只拷贝了一层,它不会去处理嵌套的对象,如oldObj.friend.name的值
所以我们不能直接赋值,应该在函数里面应该递归的调用函数本身;完成嵌套对象的值的深拷贝
for(let key in obj){
result[key]=deepClone(obj[key])
}
还有一个优化点是,应该只拷贝原来对象上自身的属性,原来对象原型上的属性不应该拷贝
for(let key in obj){
if(obj.hasOwnProperty(key)){
result[key]=deepClone(obj[key])
}
}
遗留点: 没有讲循环引用问题
循环引用解决思路:添加一个参数cache,里面存储处理过的参数,当遇到循环引用时,将cache中存储的信息返回即可
参考B站up“左耳击水兽”
1、JSON.parse(JSON.stringify())
- 优点:二层及以上可以实现深拷贝
- 缺点
- 无法拷贝函数
- 无法拷贝正则
- 无法拷贝undefined
2、借助第三方库lodash实现深拷贝
浅拷贝方式2
var shallowObj2 = { ...obj1 }
浅拷贝实现方式3
2、Object.assign()
- 优点
- 可以拷贝函数
- 可以拷贝正则
- 可以拷贝undefined
- 缺点 :二层及以上无法实现深拷贝
参考:
- 书籍《JavaScript 语言精粹(修订版)》
- CSDN平台博主“晟小明”<身为三本的我就是凭借这些前端面试题拿到百度京东offer的,前端面试题2021及答案>
- B站up“前端小野森森-2”
- B站up“左耳击水兽”
边栏推荐
- Xcode13.1 real machine debugging
- 2022 Shandong Province Safety Officer C Certificate Exam Practice Questions and Mock Exam
- MySQL - 索引优化
- PriorityQueue(优先队列)
- HyperBDR云容灾深度解析二:自研Boot in Cloud技术,实现高度自动化云容灾
- 为什么NIO比BIO效率高
- Unity Shader: Blend混合
- 赋值、深拷贝、浅拷贝、堆和栈
- leetcode 110. 平衡二叉树
- Top 20 most popular plugins for QGIS
猜你喜欢

The spyder/conda installation package reports an error: conda info could not be constructed. KeyError: 'pkgs_dirs'

cron 表达式

LeetCode 628. 三个数的最大乘积

【小题练手】----平方矩阵

The regular expression of the shell and the Three Musketeers grep command

程序员福音,关于如何使用Markdown写出一份漂亮的简历 —— 程序员简历 | md文档简历制作教程

C trap - infinite loop problem caused by array out of bounds

grid网格布局

VoLTE基础自学系列 | 什么是VoLTE中的透明数据及非透明数据?

How to use the @Async annotation
随机推荐
Graph Theory and Network Models - Based on R
LeetCode 剑指 Offer 06. 从尾到头打印链表
grid网格布局
[acwing周赛复盘] 第 63 场周赛20220806
spyder/conda安装包报错:conda info could not be constructed. KeyError: ‘pkgs_dirs‘
2022A特种设备相关管理(电梯)特种作业证考试题库模拟考试平台操作
leetcode 110. Balanced Binary Trees
VoLTE基础自学系列 | 汇总
C陷阱——数组越界引发的死循环问题
VoLTE Basic Self-Learning Series | The relationship between IMS, VOIP, VoLTE, and RCS?
Why NIO is more efficient than BIO
Tag: top stack
Xcode13.1 real machine debugging
Ali cloud message service, SMS
OC-run loop
通过定位实现评论弹幕效果
360 Digital Security Brain of the Whole Network Won the "Digital Economy Innovation Leading Achievement" Award
servlet tutorial 1: environment setup and new servlet project
图解LeetCode——1408. 数组中的字符串匹配(难度:简单)
TRACE32——Step