JavaScript中的深浅拷贝
2024-10-07 00:41:40
深浅拷贝
在JS中,数据类型分为两类:
简单数据类型:Number、Boolean、String、undefined
引用数据类型:Array、Object、Function
简单数据类型通常的操作为赋值,引用数据类型就是增删改插等操作了
深浅拷贝就是对引用数据使用的。
浅拷贝
理解:存在一个“指针”指向某块内存,再增加一个“指针”指向该内存;如果这个内存发生改变,那么,新增指针也会发生改变。
特点:无法切断数组内部引用数据类型的引用关系。
代码分析:
案例一:
<script>
var arr1 = [1,2,3,4,5]
var arr2 = arr1;
arr1.splice(2,3); // 删除索引为2开始以后的3项(包括索引为2 的项)
console.log(arr1); // [1, 2]
console.log(arr2); // [1, 2]
</script>
这是一个简单的浅拷贝,首先声明一个arr1的数组,然后又声明arr2 的数组,并且把arr1赋给arr2,然后删除arr1 的项,arr2也跟着改变,这就是浅拷贝。
案例二:
var obj1 = {
name: 'hf',
age: 23,
gender: '男',
friends: {
boy: 'zs',
gril: {
person1: 'ls',
person2: 'ww'
}
},
sayHi: function () {
consoloe.log("我有三个朋友");
}
};
var obj2 = {};
for (var k in obj1) {
obj2[k] = obj1[k];
}
delete obj1.friend.boy; //将obj1中的friends对象的boy键值对删除
console.log(obj1);
console.log(obj2);
可见,将obj1中的friends对象的boy键值对删除,obj2 中的对应项也会删除,这是为什么呢?
解释一下:通过for in 来拷贝对象时,如果键值对就是普通的name:value时,那么就把内存拷贝一份(这是深拷贝);如果对象里面的某个键值对也是对象的话,那么就是增加一个新的指针,指向obj1的键值对象,没有开辟一份新的地址,依然指向原来的地址,不会像普通的键值对再复制一份,所以就发生以上删除obj1中的friends对象的boy键值对,obj2的对应项也会删除的情况!
深拷贝
深拷贝就是新增加一个“指针”,指向一块新开辟的内存,然后拷贝某个对象或数组,当释放这个对象或数组时,这个深拷贝的对象或数组不会随着释放掉。
特点:彻底切断了数组内引用类型的引用关系。
<script>
// obj1 为将要拷贝的对象
// obj2 为拷贝到的目标对象
function deepCopy(obj1,obj2) {
for (var k in obj1) {
// 如果键值对不是object或者null类型的
if (typeof obj1[k] != "object" || typeof obj1[k] === null) {
obj2[k] = obj1[k]; // 基本数据进行浅拷贝
} else {// 如果复杂数据类型值有可能是对象,也有可能是数组,需要进行判断后再设置
obj2[k] = obj1[k] instanceof Array ? []:{};
// 再把这个是数组或者是对象的“键值对”调用函数
deepCopy(obj1[k],obj2[k]);
}
}
}
var obj1 = {
name: 'hf',
age: 23,
gender: '男',
friends: {
boy: 'zs',
gril: {
person1: 'ls',
person2: 'ww'
}
},
sayHi: function () {
consoloe.log("我有三个朋友");
}
};
var obj2 = {};
deepCopy(obj1,obj2);
delete obj1.friends.boy; //将obj1中的friends对象的boy键值对删除,但是对obj2中的数据没哟影响
console.log(obj1);
console.log(obj2);
</script>
最新文章
- java主函数的含义
- Michael Schatz - 序列比对课程
- include,import,@class的区别
- isDebugEnabled有什么用?
- Linux 信号详解一(signal函数)
- javascript打乱数组顺序-----1
- UU农场平台开发 UU农场拆复利系统
- 阿里云API网关(13)请求身份识别:客户端请求签名和服务网关请求签名
- C语言--第3次作业
- DB9 ------ 接口定义
- 使用iperf测试网卡吞吐性能
- 非阻塞IO发送http请求
- Jmeter录制浏览器并回放
- mysql表操作与权限操作
- C# CLR20R3 程序终止的几种解决方案
- Pandas dataframe 标记删除重复记录
- JDBC数据库连接池
- Android Studio- 把项目提交到SVN中操作方法
- 如何用vs查看框架函数管道模型
- oradebug工具使用(转载)