深拷贝、浅拷贝
2021-07-26 本文已影响0人
清苑折纸
深拷贝和浅拷贝只针对引用数据类型,比如Object和Array
深拷贝:从A拷贝到B,当A发生改变时B不会变;
浅拷贝:从A拷贝到B,当A发生变化时B也会变,此时是只复制了指向对象的指针而没有复制对象的值。
浅拷贝
- 循环
function shallowCopy(oldObj){
var newObj = {}
for(var i in oldObj){
if(oldObj.hasOwnProperty(i)){
newObj[i] = oldObj[i]
}
}
return newObj
}
-
object.assign(target, source):
将所有可枚举值从一个或多个源对象复制到目标对象,会修改目标对象,可将目标对象设置为空。
Object.assign( {} , source,source);
当对象只有一级属性没有二级属性的时候,属于深拷贝,但是当对象中还有对象时,在二级属性后就属于浅拷贝。
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target); // { a: 1, b: 4, c: 5 }
console.log(returnedTarget); // Object { a: 1, b: 4, c: 5 }
console.log(target) // {a: 1, b: 4, c: 5}
第一级是深拷贝:
let a = {James: {age: 18}}
let b = Object.assign({}, a)
b.James = 20
console.log(b) // { James: 20 }
console.log(a) // { James: { age: 18 } }
以后各级是浅拷贝:
let a = {James: {age: 18}
let b = Object.assign({}, a)
b.James.age = 20
console.log(b) // { James: { age: 20 } }
console.log(a) // { James: { age: 20 } } //源对象a也被修改
-
Array.prototype.concat()
-
Array.prototype.slice()
concat和slice都不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。
如果原数组的元素是对象引用,则slice会拷贝引用到新数组;
如果是字符串、数字和布尔值,则拷贝值到新对象,此时修改其中一个数组的值时不会影响另一个数组。
深拷贝
- 手动拷贝
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }
- JSON.parse(JSON.stringify()),不能拷贝对象中的方法
let arr = [1, 2, {
username: 'aa'
}];
let arr2=JSON.parse(JSON.stringify(arr));
arr2[2].username = 'bb';
console.log(arr,arr2);
- JQuery的extend
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f);
// false
- 递归方法
function deepCopy(oldObj){
var newObj = {}
for(var key in oldObj){
if(typeof oldObj[key] === 'object'){
newObj[key] = deepCopy(oldObj[key])
}else{
newObj[key] = oldObj[key]
}
}
return newObj
}