深拷贝
先来理解一下什么是深拷贝:就是复制出一个新的对象,不能修改它所拥有的全部数据,包括数据类型,但是绝对不能相等,也就是说==为false。
第一种情况:如果内部没有引用数据,或者时间正则null等等数据时。
如果我创建了一个对象obj1,这个时候我要拷贝一份obj1里面的内容以保证我修改obj2内容时,obj1对象不受影响,也就是说在内存中重新申请一个空间。
var obj1 = {
name: 'karen'
}
//这种方法不推荐使用,因为还要去看obj1里面的成员,多了无法实现
// var obj2 = {};
// obj2.name = obj1.name;
//巧妙利用JSON字符串的转换完成拷贝
var str = JSON.stringify(obj1);
var obj2 = JSON.parse(str);
//检测是否是同一个对象
console.log(obj1 == obj2);
//false
第二种情况(笔试频率特别高和垂直水平居中差不多):
例如:拷贝事件对象
var dt = new Date();
var dt2 = JSON.parse(JSON.stringify(dt));
console.log(typeof dt2);//打印出来的不是date而是string
如果拷贝事件对象的话,用我们前面的方法来拷贝就会出现错误,拷贝过去的不是事件对象,而是字符串,所以我们要学习更高级的拷贝方法:
自己封装一个函数(背下来):
方法1. 最简单的方式,缺陷是原型链没有拷贝 函数和null不会拷贝;
var copy1 = function (obj) {
return JSON.parse(JSON.stringify(obj));
}
var a = {a:function(){console.log('hello world')},b:{c:1},c:[1,2,3],d:"wanger",e:new Date(),f:null,g:undefined}
var b = copy1(a)
方法2.利用自调用;
var obj = {
o1: 'hello',
o2: [1, 23, [3, 2]],
o3: null
};
var copy1 = function (obj) {
if (obj === null) return null
if (typeof obj !== 'object') return obj;
if (obj.constructor === Date) return new Date(obj);
if (obj.constructor === RegExp) return new RegExp(obj);
var newObj = new obj.constructor(); //保持继承链
for (var key in obj) {//这里可以用object.key(obj)
if (obj.hasOwnProperty(key)) { //不遍历其原型链上的属性
var val = obj[key];
newObj[key] = typeof val === 'object' ? arguments.callee(val) :
val; // 使用arguments.callee解除与函数名的耦合
}
}
return newObj;
};
var obj2 = copy1(obj);
console.log(obj2);