前言
数据在内存中的存储方式:
栈存储:存储基本数据类型的数值和引用数据类型的地址
堆存储:存储引用数据类型的地址。
浅拷贝:引用类型的传址
深拷贝:引用类型的传值 只将数值传给新对象
深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。
1、for…in循环
只能深拷贝第一层,如果对象中属性也是对象的话,没办法进行深层拷贝。
<script>
let obj={name:'小明',age: 20,}
let objNew = {}
for(x in obj) {
objNew[x] = obj[x]; //因为对象是无序的,只需要赋值属性值即可
}
console.log(objNew); //{name: '小明', age: 20}
objNew.sex = '男生';
console.log(objNew); //{name: '小明', age: 20, sex: '男生'}
console.log(obj); //{name: '小明', age: 20}
</script>
2、ES6中的解构赋值
只能深拷贝第一层,如果对象中属性也是对象的话,没办法进行深层拷贝。
<script>
let obj = {
name: "小阿虎",
age: 18,
eat:{
x:1
}
};
let obj1 = { ...obj };
console.log(obj1); //{name: '小阿虎', age: 18, eat{}}
obj1.sex = "女";
console.log(obj1); //{name: '小阿虎', age: 18, eat{}, sex: '女'}
console.log(obj); //{name: '小阿虎', age: 18, eat{}}
obj1.eat.x = 2;
console.log(obj1.eat.x); //2
console.log(obj.eat.x); //2
//注:只可以深拷贝一层,eat对象是浅拷贝
</script>
3、ES6中对象的合并
Object.assign(target,origin)
将源对象origin的属性赋值到目标对象target上,如果遇到重复属性会覆盖掉
第一个参数必须是个空对象
只能深拷贝第一层,如果对象中属性也是对象的话,没办法进行深层拷贝。
<script>
let origin = {
name: "小阿虎",
age: 18,
eat: {
x: 1,
},
};
let target = {};
Object.assign(target, origin);
console.log(target); //{name: '小阿虎', age: 18, eat: {…}}
target.age = 19;
console.log(target); //{name: '小阿虎', age: 19, eat: {…}}
console.log(origin); //{name: '小阿虎', age: 18, eat: {…}}
target.eat.x = 3;
console.log(target); //3
console.log(origin); //3
</script>
4、利用JSON
先通过JSON.stringify()将对象转为json字符串,再通过JSON.parse()转为对象。
有局限性:当值为undefined、function、symbol会在转换过程中被忽略。
可以深拷贝多层,如果对象的属性是对象的话也可以进行深拷贝。
<script>
let obj1 = {name:'小明',age:20};
// 先转为JSON字符串,再转为JSON对象
let obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj2); //{name: '小明', age: 20}
obj2.sex = '男生';
console.log(obj2); //{name: '小明', age: 20, sex: '男生'}
console.log(obj1); //{name: '小明', age: 20}
</script>
5、利用循环和递归
可以深拷贝多层,如果对象的属性是对象的话也可以进行深拷贝。
function deepClone(obj, newObj) {
var newObj = newObj || {};
for (let key in obj) {
if (typeof obj[key] == 'object') {
newObj[key] = (obj[key].constructor === Array) ? [] : {}
deepClone(obj[key], newObj[key]);
} else {
newObj[key] = obj[key]
}
}
return newObj;
}