
实现深拷贝
js
// 简单版本
const newObj = JSON.parse(JSON.stringify(oldObj))
// 面试够用版
function deepClone(obj) {
// 如果是值类型 或 null, 则直接return
if (typeof obj !== 'object' || obj === null) {
return obj
}
// 定义结果对象
let copy = {}
// 如果对象是数组,则定义结果数组
if (obj.constructor === Array) {
copy = []
}
// 遍历对象的key
for (let key in obj) {
// 如果key是对象自有属性
if (obj.hasOwnProperty(key)) {
// 递归调用深拷贝方法
copy[key] = deepClone(obj[key])
}
}
return copy
}js
// 深拷贝
function isObject(val) {
return typeof val === 'object' && val !== null
}
function deepClone(obj, hash = new WeakMap()) {
if (!isObject(obj)) return obj
if (hash.has(obj)) {
return hash.get(onj)
}
let target = Array.isArray(obj) ? [] : {}
hash.set(obj, target)
Reflect.ownKeys(obj).forEach((item) => {
if (isObject(obj[item])) {
target[item] = deepClone(obj[item], hash)
} else {
target[item] = obj[item]
}
})
return target
}
var obj1 = {
a: 1,
b: { a: 2 },
}
var obj2 = deepClone(obj1)
console.log(obj1)js
// 浅拷贝
// concat、slice、JSON.stringify 都算是技巧类
var shallowCopy = function (obj) {
// 只拷贝对象
if (typeof obj !== 'object') return
// 判断是数组还是普通对象
var newObj = obj instanceof Array ? [] : {}
// 遍历obj,并且判断是obj的属性才拷贝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key]
}
}
return newObj
}
// 深拷贝
var deepCopy = function (obj) {
if (typeof obj !== 'object') return
var newObj = obj instanceof Array ? [] : {}
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
}
}
return newObj
}
// Object.assign也是浅拷贝,如果是对象的化拷贝的是地址
// ...也可以实现浅拷贝
//JSON.parse(JSON.stringify(object))是深拷贝但是有局限
/**
* 会忽略 undefined
会忽略 symbol
不能序列化函数
不能解决循环引用的对象
*/
//推荐使用lodsh深拷贝
function deepClone(obj) {
function isObject(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null
}
if (!isObject(obj)) {
throw new Error('非对象')
}
let isArray = Array.isArray(obj)
let newObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(newObj).forEach((key) => {
newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return newObj
}
let obj = {
a: [1, 2, 3],
b: {
c: 2,
d: 3,
},
}
let newObj = deepClone(obj)
newObj.b.c = 1
console.log(obj.b.c) // 2
