对象的浅层克隆和深层克隆
2020-06-30 本文已影响0人
63537b720fdb
浅层克隆:将a对象里的所有属性赋给一个b的空对象,若a对象中存在引用值,则克隆后修改b中的引用值,a也会跟着修改,因为引用值传的是地址
举例:
var obj = {
name : 'sunny',
age : 18,
car : ['car0','car1','car2'],
study: {
time : 'long',
book : ['book0','book1']
}
}
var obj1 = {}
function clone(origin,target) {
var target = target || {}; //容错机制,防止用户没有设置target对象
for(var prop in origin) { //遍历origin里的属性
target[prop] = origin[prop]; //克隆
}
return target;
}
clone(obj,obj1)
给obj1的car对象中添加red值,obj也跟着改变
image.png
原始值:number、string、boolean、undefined、null
typeof()的返回值:number、string、boolean、undefined、object、function
注意:typeof(null) 返回object
判断数组的三种方式:
1.constructor
image.png
2.A instanceof B
B是否是A对象的构造函数,其实就是A对象的原型链上是否有B的原型
image.png
3.Object.prototype.toString.call() image.png
深层克隆:克隆完成后,两个对象互不影响。
思路:
1.判断是原始值还是引用值,可用typeof()
2.判断是数组还是对象,建议使用Object.prototype.toString.call()
3.如果是数组,就新建一个空数组,如果是对象,就新建一个空对象
4.数组和对象里可以存原始值可以存引用值,所以还需将数组或对象中的值从第一步开始判断是原始值还是引用值,一直重复到第4步,所以可以采用递归的方式。
5.由第2步判断可知,如果是原始值就使用浅克隆的方式
var obj = {
name : 'sunny',
age : 18,
car : ['car0','car1','car2'],
study: {
time : 'long',
book : ['book0','book1']
}
}
var obj1 = {}
function deepClone(origin,target) {
var target = target || {};
var toStr = Object.prototype.toString,
arrStr = "[object Array]";
for(var prop in origin) {
//typeof(null)-->'object' 所以要多加一条判断
if(typeof(origin[prop]) == 'object' && origin[prop] !== 'null') {
//引用值
//判断是数组还是对象,使用Object.prototype.toString.call()
if(toStr.call[origin[prop]] == arrStr) {
//数组
//创建新数组
target[prop] = [];
}else{
//对象
//创建空对象
target[prop] = {};
}
//用递归从第一步开始判断
deepClone(origin[prop],target[prop]);
}else{
//原始值
target[prop] = origin[prop];
}
}
return target;
}
deepClone(obj,obj1);
改变obj1中的引用值,obj不发生改变
image.png