浅拷贝
1.直接=号赋值
例如: let obj1 = obj
2.Object.assign()
例如: let obj1 = Object.assign(obj)
深拷贝
1.Object.assign( {}, obj )
例如: let obj1 = Object.assign({}, obj)
注:此方法只针对obj对象里的基本数据类型深拷贝,对象里的引用数据类型依然浅拷贝
2.es6中的解构
例如: let obj1 = { …obj }
注:此方法只针对obj对象里的基本数据类型深拷贝,对象里的引用数据类型依然浅拷贝
3.JSON.parse(JSON.stringify())
例如: let obj1 = JSON.parse(JSON.stringify(obj))
注:该方法虽然可对obj对象里的基本数据类型和引用数据类型进行深拷贝,但无法拷贝obj对象里的function
4.手写递归
注:该方法可实现完全深拷贝(强烈推荐)
代码如下
deepCopy(obj) {
let newobj = obj.constructor === Array ? [] : {}
if (typeof obj !== "object") {
return obj
} else {
for (const i in obj) {
if (typeof obj[i] === "object") {
//判断对象的这条属性是否为对象
newobj[i] = deepCopy(obj[i]) //若是对象进行嵌套调用
} else {
newobj[i] = obj[i]
}
}
}
return newobj //返回深度克隆后的对象
},
以下是深浅拷贝各种方法的代码实现,大家也可以自己去论证一下,毕竟只有亲自敲了才会印象更深刻嘛!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
var app = new Vue({
el: "#app",
data: {
message: "Hello Vue!",
},
created() {
// this.simpleCopy1()
// this.simpleCopy2()
// this.deepCopy1()
// this.deepCopy2()
// this.deepCopy3()
this.deepCopy4()
},
methods: {
simpleCopy1() {
let obj1 = {
name: "aaa",
desc: {
sex: "男",
},
fun: function () {
console.log("333")
},
}
let obj2 = obj1
obj2.name = "bbb"
obj2.desc.sex = "女"
console.log("obj1", obj1) // desc: {sex: '女'}, fun: ƒ (), name: "bbb"
console.log("obj2", obj2) // desc: {sex: '女'}, fun: ƒ (), name: "bbb"
},
simpleCopy2() {
let obj1 = {
name: "aaa",
desc: {
sex: "男",
},
fun: function () {
console.log("333")
},
}
let obj2 = Object.assign(obj1)
obj2.name = "bbb"
obj2.desc.sex = "女"
console.log("obj1", obj1) // desc: {sex: '女'}, fun: ƒ (), name: "bbb"
console.log("obj2", obj2) // desc: {sex: '女'}, fun: ƒ (), name: "bbb"
},
// JSON.parse(JSON.stringify()) 不会对对象中的function进行深拷贝
deepCopy1() {
let obj1 = {
name: "aaa",
desc: {
sex: "男",
},
fun: function () {
console.log("333")
},
}
let obj2 = JSON.parse(JSON.stringify(obj1))
obj2.name = "bbb"
obj2.desc.sex = "女"
console.log("obj1", obj1) // desc: {sex: '男'}, fun: ƒ (), name: "aaa"
console.log("obj2", obj2) // desc: {sex: '女'}, name: "bbb"
},
// 解构只可对obj1里的基本类型实现深拷贝,对引用类型还是浅拷贝
deepCopy2() {
let obj1 = {
name: "aaa",
desc: {
sex: "男",
},
fun: function () {
console.log("333")
},
}
let obj2 = { ...obj1 }
obj2.name = "bbb"
obj2.desc.sex = "女"
console.log("obj1", obj1) // desc: {sex: '女'}, fun: ƒ (), name: "aaa"
console.log("obj2", obj2) // desc: {sex: '女'}, fun: ƒ (), name: "bbb"
},
// Object.assign({}, obj1)只可对obj1里的基本类型实现深拷贝,对引用类型还是浅拷贝
deepCopy3() {
let obj1 = {
name: "aaa",
desc: {
sex: "男",
},
fun: function () {
console.log("333")
},
}
let obj2 = Object.assign({}, obj1) // 一定要写target
obj2.name = "bbb"
obj2.desc.sex = "女"
console.log("obj1", obj1) // desc: {sex: '女'}, fun: ƒ (), name: "aaa"
console.log("obj2", obj2) // desc: {sex: '女'}, fun: ƒ (), name: "bbb"
},
// 递归 可实现任意类型深拷贝 (推荐使用)
deepCopy4() {
let obj1 = {
name: "aaa",
desc: {
sex: "男",
},
fun: function () {
console.log("333")
},
}
let obj2 = this.deepCopy(obj1) // 一定要写target
obj2.name = "bbb"
obj2.desc.sex = "女"
console.log("obj1", obj1) // desc: {sex: '男'}, fun: ƒ (), name: "aaa"
console.log("obj2", obj2) // desc: {sex: '女'}, fun: ƒ (), name: "bbb"
},
deepCopy(obj) {
let newobj = obj.constructor === Array ? [] : {}
if (typeof obj !== "object") {
return obj
} else {
for (const i in obj) {
if (typeof obj[i] === "object") {
//判断对象的这条属性是否为对象
newobj[i] = this.deepCopy(obj[i]) //若是对象进行嵌套调用
} else {
newobj[i] = obj[i]
}
}
}
return newobj //返回深度克隆后的对象
},
},
})
</script>
</html>