深拷贝通常使用会使用JSON.parse(JSON.stringify(object))来实现, 但是该方法有局限性:
- 会忽略undefined
- 不能序列化函数
- 性能差,根据网上的数据大概比遍历慢几倍
- 无法实现对函数 、RegExp等特殊对象的克隆
- 会抛弃对象的constructor,所有的构造函数会指向Object
- 对象有循环引用,会报错
- 含有symbol属性名的对象拷贝会漏掉symbol属性
const obj = {
//fun: function name(params) {...},
//name:undefined,
//reg:/abc/
}
console.log(obj);// { fun: [Function: name] }
console.log(obj);// { name: undefined }
console.log(obj);// { name: /abc/ }
const temp = JSON.parse(JSON.stringify(obj))
console.log(temp);// {}
递归
// 递归
function deepClone(obj) {
const objectMap = new Map()
const _deepClone = (value) => {
const type = typeof value
if (type !== 'object' || type === null) {
return value
}
if (objectMap.has(value)) {
return objectMap.get(value)
}
const result = Array.isArray(value) ? [] : {}
objectMap.set(value, result)
for (const key in value) {
result[key] = _deepClone(value[key])
}
return result
}
return _deepClone(obj)
}
MessageChannel 介绍:MessageChannel创建了一个通信的管道,这个管道有两个端口,每个端口都可以通过postMessage方法发送数据,另一个端口只要调用onmessage方法,就可以接收从另一个端口传过来的数据。如
// MessageChannel
const obj = { a: 1, b: 2 }
function deepClone(obj) {
return new Promise((resolve) => {
const { port1, port2 } = new MessageChannel() // 实例化了一个 channel 对象
port1.postMessage(obj) // 通过postMessage方法把数据传递
port2.onmessage = msg => { // 通过onmessage方法监听事件接收到信息
resolve(msg.data)
}
})
}
deepClone(obj).then(res => {
console.log(res) //
})