深度克隆
- 对于基本数据类型,例如 string number boolean之类的没有克隆深浅的概念
- 对于引用数据类型,像数组和对象,就有克隆的深浅之分,浅拷贝就是拷贝之后会影响原来的数据,深拷贝(深度克隆)就是拷贝之后不会影响原来的数据
浅拷贝
const zhangsan = {
name:"zhangsan",
age:24,
gender:"man"
}
const lisi = zhangsan
lisi.name = "lisi"
console.log(lisi) // { name: 'lisi', age: 24, gender: 'man' }
console.log(zhangsan) // { name: 'lisi', age: 24, gender: 'man' }
- 可以看见直接把 zhangsan 这个对象赋给 lisi 之后,当 lisi 改变 name 属性之后,zhangsan 这个对象的 name 属性也改变了,因为这两个对象是同一个地址,因此一个改变会导致另一个也会发生改变,这就是浅拷贝
那么怎么做才可以深度拷贝呢?
- 首先要明白为什么要使用深度拷贝?因为在处理大量数据的时候,你并不知道这些引用类型的数据哪些重要哪些不重要,为此不可以轻易的改变数据,于是深度拷贝就变得很重要了
深度拷贝的方法
- json方法,即 JSON.parse(JSON.stringify(引用数据))
const zhangsan = {
name:"zhangsan",
age:24,
gender:"man"
}
const lisi = JSON.parse(JSON.stringify(zhangsan))
lisi.name = "lisi"
console.log(lisi) // { name: 'lisi', age: 24, gender: 'man' }
console.log(zhangsan) // { name: 'zhangsan', age: 24, gender: 'man' }
- 这样做之后,lisi 和 zhangsan 就没有关系了,lisi 的数据改变不会影响 zhangsan 数据的改变,这就是 深度克隆
- 利用对象解构
const zhangsan = {
name:"zhangsan",
age:24,
gender:"man"
}
const lisi = {...zhangsan}
lisi.name = "lisi"
console.log(lisi) // { name: 'lisi', age: 24, gender: 'man' }
console.log(zhangsan) // { name: 'zhangsan', age: 24, gender: 'man' }
- 这是 ES6 的语法了,也很简单
- webworker
实际上利用 webworker 也是可以实现深度拷贝的,这只是一个实现的方式,但是不建议使用
- index.js
const work = new Worker("./count.js")
class People{
constructor(name,age,gender){
this.name = name
this.age = age
this.gender = gender
}
sayName(){
console.log(`My name is ${this.name}`)
}
}
const peo1 = new People("zhangsan",24,"man")
let peo2 = null
work.postMessage(peo1)
work.onmessage = function(event){
peo2 = event.data
peo2.name = "lisi"
console.log(peo2) // { name: "lisi", age: 24, gender: "man" }
console.log(peo1) // { name: "zhangsan", age: 24, gender: "man" }
}
- count.js
self.onmessage = function(event){
self.postMessage(event.data)
}
- index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>webwork</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
这个方法的原理我感觉和 json方法 有异曲同工之妙