假设有一个a变量 b复制a 当修改a时 b跟着改变 说明是浅拷贝,
当修改a时b不改变 说明是深拷贝。
下面这段代码a改变时b跟着改变,说明是浅拷贝。
var a = {
name:'xx'
};
var b = a;
console.log(b); // xx
a.name = 'cc';
console.log(b); // cc
为什么a改变的时候b也跟着改变?
因为 JavaScript 存储对象都是存地址 b对象只是指向了这个地址 当用到b对象时 b会向这个地址中去取变量来用 但当a改变时 这个地址中的变量也跟着改变了,所以当a改变之后,b再去取值得时候值已经发生了变化。
实现浅拷贝的方法:
浅拷贝是使用遍历对象 拿到对象的 每个属性 并把这些属性存到一个新的对象中 然后返回出去的方法
function simpleCopy(obj1) {
var obj2 = Array.isArray(obj1) ? [] : {};
for (let i in obj1) {
obj2[i] = obj1[i];
}
return obj2;
}
var obj1 = {
a: 1,
b: 2,
c: {
d: 3
}
}
var newObj = simpleCopy(obj1);
实现深拷贝的方法:
深拷贝也是采用遍历对象,然后生成新对象的方法实现,但是采用了闭包去拷贝所有层级的属性。
hasOwnProperty()方法可以检测对象是否有某个属性。
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
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;
}
通过json对对象实现深拷贝
使用json的parse和stringify方法解析
function deepClone2(obj) {
var objClone = JSON.parse(JSON.stringify(obj));
return objClone;
}
缺点: 无法实现对对象中方法的深拷贝,会显示为undefined
通过jQuery的extend方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝
使用扩展运算符实现深拷贝
var car = {brand: "BMW", price: "380000", length: "5米"}
var car1 = { ...car, price: "500000" }
console.log(car1); // { brand: "BMW", price: "500000", length: "5米" }
console.log(car); // { brand: "BMW", price: "380000", length: "5米" }