浅拷贝拷贝的是指针,深拷贝拷贝的是地址
1.浅拷贝
改变其中一个变量另一个变量也会跟着改变
2.深拷贝
改变其中一个变量,另一个变量不会跟着改变
常用的深拷贝的方法
1 ...扩展运算符 只能实现单一层次(第一层次)
2 JSON.parse(JSON.stringify(obj))
原因:先将数据转为字符串存储在栈中,再反序列化转为对象形式在堆中重新存储一份,与原数据存储地址不同
缺点:数据里的undefined和函数不能解析,性能比较低
使用如上对象obj:
3. assign(合并)
4. 递归函数
<script>
let obj = {
num: 0,
o: {
n: 0,
o: {
n: 0
}
}
}
let obj1 = {}
function fn(obj, obj1) {
for (let key in obj) {
if (typeof obj[key] == 'object') {
obj1[key] = {}
fn(obj[key], obj1[key])
} else {
obj1[key] = obj[key]
}
}
}
fn(obj, obj1)
obj.num = 10
console.log(obj1) // {num:0,o:{n:0,o:{n:0}}}
// fn(obj,{}) for *1
// num obj1:{num:0}
// o obj1:{num:0,o:{}}
// fn(obj.o,obj1.o) obj1.o={} for *2
// n obj1.o={n:0}
// o obj1.o={n:0,o:{}}
// fn(obj.o.o,obj1.o.o) obj1.o.o={} for *3
// n obj1.o.o={n:0}
</script>
5.vue2项目中,对象没有要操作的属性,通过this.对象名.操作的属性=值,视图不会更新,但是对象里的数据已经发生改变。
由于Object.defineProperty只会监听对象中已有的属性,通过this.$set()可以将对象中的数据强制改变,视图更新。
<template>
<div class="home">
{{ obj }}
<button @click="add">++</button>
</div>
</template>
<script>
export default {
name: 'HomeView',
data() {
return {
obj: {}
}
},
methods: {
add() {
this.obj.num = 100 // 不会更新视图
this.$set(this.obj, 'num', 100) // 会更新视图
console.log(this.obj); // 数据发生改变
}
}
}
</script>