深拷贝:完整的把数据的任意层级属性和值拷贝到新数据上,拷贝前后的两个数据完全一样,但是是不同的地址,相互不会影响。
1.
/** 返回克隆后的对象 */
MixinClone(obj) {
return JSON.parse(JSON.stringify(obj))
},
2.
let arr = {
name: 'zhangsan',
age: 18,
family: {
mather: 'mary',
father: 'tom',
brother: 'ah'
}
}
// 判断是否是对象或者数组(返回的是布尔值)
function isObject(data) {
return Object.prototype.toString.call(data) === '[object Array]' || Object.prototype.toString.call(data) === '[object Object]'
}
function objectDeepClone(data) {
// 1.判断data 是否是数组/对象
if (!this.isObject(data)) {
return data
}
// 2. 递归
const obj = Array.isArray(data)? [] : {}
for (const x in data) {
if (this.isObject(data[x])) {
obj[x] = objectDeepClone(data[x])
} else {
obj[x] = data[x]
}
}
return obj
}
objectDeepClone(arr)
console.log(objectDeepClone(arr), 'console数据============')
3.优化后(堆栈溢出,原因便是会一直执行递归,我们克隆的时候需要考虑该对象是否已被克隆,如果克隆过便记录下来。)
/**
* 判断是不是数组和对象
* @param {*} data 要判断的数据
* @returns true 是 | false 否
*/
MixinIsObject(data) {
return Object.prototype.toString.call(data) === '[object Array]' || Object.prototype.toString.call(data) === '[object Object]'
},
/**
* 深拷贝函数
* @param {*} data 待拷贝的数据
* @param {*} hash 利用Map数据结构来解决循环引用造成死循环的问题
* @returns 深拷贝后的数据
*/
MixinDeepClone(data, hash = new Map()) {
// 1. 判断类型,只适用于array和object
if (!this.MixinIsObject(data)) {
return data
}
// 2. 如果已经被克隆过了, 就直接return
// map.has(key) —— 如果 key 存在则返回 true,否则返回 false
if (hash.has(data)) {
return hash.get(data)
}
const obj = Array.isArray(data) ? [] : {}
// 3. 如果不存在, 将data存入到map中进行克隆
// 键值对的存储, 是因为步骤2要判断key
hash.set(data, obj)
for (const k in data) {
if (this.MixinIsObject(data[k])) {
obj[k] = this.MixinDeepClone(data[k], hash)
} else {
obj[k] = data[k]
}
}
return obj
}