
出现原因
出现深浅拷贝的问题,实质上是由于JS对基本类型和引用类型的处理不同。基本类型指的是简单的数据段,而引用类型指的是一个对象,而JS不允许我们直接操作内存中的地址,也就是不能操作对象的内存空间,所以对对象的操作都只是在操作它的引用而已。
如果我们复制一个基本类型的值时,会创建一个新值,并把它保存在新的变量的位置上。
而如果我们复制一个引用类型时,同样会把变量中的值复制一份放到新的变量空间里,但此时复制的东西并不是对象本身,而是指向该对象的指针。所以我们复制引用类型后,两个变量其实指向同一个对象,改变其中一个对象,会影响到另外一个。
js 数据类型
- 基本类型(单类型):除Object。 String、Number、boolean、null、undefined。
- 引用类型:object。里面包含的 function、Array、Date
我们操作基本类型的时候,拷贝和复制都不会出现引用问题
var a=10;
var b=a;
b=15;
console.log(a,b);//10,15,
这个a变量并没有被改变,因为它是基本类型
var arr=[
{name:"a"},
{name:"b"}
];
var arr2=arr;
arr[0].name="a-update";
console.log(arr,arr2);
这个时候就出现了浅拷贝的现象,我们并不想 arr2
也被修改了。因为我们复制的只是引用地址
内部实现了浅拷贝
- Object.assign() 实现
- slice()方法
var arr1 = ['red','green'];
var arr2 = arr1.slice(0);//复制
console.log(arr2)//['red','green'];
arr1.push('black') ;//改变color1的值
console.log(arr2)//["red", "green"]
console.log(arr1)//["red", "green", "black"]
看起来像是深拷贝,其实slice方法只适用于一维数组的拷贝,在二维数组中就会破绽百出
- concat
var arr1 = ['red','green'];
var arr2 = arr1.concat();//复制
console.log(arr2)//['red','green'];
arr1.push('black') ;//改变color1的值
console.log(arr2)//["red", "green"]
console.log(arr1)//["red", "green", "black"]
看起来像是深拷贝,其实concat方法只适用于一维数组的拷贝,在二维数组中就会破绽百出
深拷贝方法
- JSON.parse
var arr1 = ['red','green'];
var arr2 = JSON.parse(JSON.stringify(arr1));//复制
console.log(arr2)//['red','green'];
arr1.push('black') ;//改变color1的值
console.log(arr2)//["red", "green"]
console.log(arr1)//["red", "green", "black"]
- 自定义方法
function deepClone(obj){
//判断参数是不是一个对象
let objClone = obj instanceof Object?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
总结
- 1:深拷贝只是从源数据中拷贝一份出来进行操作,而不是改变源数据;改变源数据的那是浅拷贝;
- 2:原生js方法slice、concat都不是真正意义上的深拷贝,都仅只适用于一维数组,拷贝的属性不够彻底;
- 3:实现js深拷贝我们可以通过JSON.parse(JSON.stringify())、递归以及JQuery库的extend方法来实现;
版权提示
1.除了标识原创之外,其他可能来源于网友的分享,仅供学习使用2.如您发现侵犯了您的权利,请联系我们删除
3.转载必须带本文链接,否则你将侵权
4.关于会员或其发布的相关内容均由会员自行提供,会员依法应对其提供的任何信息承担全部责任,本站不对此承担任何法律责任
0 人点赞
评论区 (0)
最新视频教程
-
-
黑白课堂
- Laravel6 全套入门实战
- 4642 2
-
-
-
黑白课堂
- Laravel6 全套入门实战
- 4557 5
-
-
-
黑白课堂
- Laravel6 全套入门实战
- 4443 0
-
-
-
黑白课堂
- Laravel6 全套入门实战
- 4066 0
-
-
-
黑白课堂
- Laravel6 全套入门实战
- 4063 0
-
最新视频课程
-
Laravel 消息通知使用
黑白课堂
284615 03年前
-
ace.js 打造一款属于你的 Web 编辑器,入门文档。
黑白课堂
15257 04年前
-
Laravel 实现 RBAC 权限管理功能 Permission 包操作
黑白课堂
14111 04年前
-
微信小程序等比例图片压缩上传,100%可用,非官方压缩方法
黑白课堂
12162 14年前
-
宝塔面板强制绑定账号修改为不强制绑定方案
黑白课堂
11348 02年前
-
wap2App 入门讲解,100%速成,全面为你讲解。
黑白课堂
9187 04年前
-
Laravel 设置请求头 header 参数
黑白课堂
8314 03年前
-
Laravel 的 PhpSpreadsheet 包入门
黑白课堂
8309 04年前
-
Laravel 表格操作 Maatwebsite/Laravel-Excel 3.1 最新版本的操作指南
黑白课堂
8286 04年前
-
Linux 下如何监听我们的脚本是否掉线了
黑白课堂
7550 02年前
-
KongQi Laravel Admin2.0 文档安装
黑白课堂
3905 23年前
-
KongQi Laravel admin2.0 layui admin 版本序言
黑白课堂
3330 03年前
-
易语言入门拖入文件导入到超级列表框表格内
哪吒
8375 13年前
-
易语言入门易语言定时任务模块
哪吒
6464 03年前
-
postman 使用手册cookie 使用
哪吒
4971 03年前
-
谷歌浏览器插件教程proxy 代理
哪吒
4506 01年前
-
易语言入门判断文件夹是否存在的方法
哪吒
4216 02年前
-
易语言入门TAB 标签页制作
哪吒
4192 03年前
-
Visual Studio Code 入门和使用教程插件安装使用
哪吒
4122 13年前
-
Visual Studio Code 入门和使用教程安装下载
哪吒
4092 03年前
