之前为了赶进度,所以遇到拷贝的问题不是简单粗暴的JSON.prase(JSON.stringify)
和Object.assign
就是直接使用lodash
中的cloneDeep方法,自己也没有深入的去好好研究这个问题,只是知道js中有简单类型和引用类型,对于引用类型,浅拷贝只是拷贝了其地址,对于简单类型就是值的复制。
所以,今天就抽空做一次总结。
浅拷贝
- 1 Object.assign
const obj = {
name: 'lin'
}
const newObj = Object.assign({}, obj)
obj.name = 'xxx' // 改变原来的对象
console.log(newObj) // { name: 'lin' } 新对象不变
- 2 slice和concat方法
const arr = ['lin', 'is', 'handsome']
const newArr = arr.slice(0)
arr[2] = 'rich' // 改变原来的数组
console.log(newArr) // ['lin', 'is', 'handsome']
const arr = ['lin', 'is', 'handsome']
const newArr = [].concat(arr)
arr[2] = 'rich' // 改变原来的数组
console.log(newArr) // ['lin', 'is', 'handsome'] // 新数组不变
- 3 数组静态方法Array.from
const arr = ['lin', 'is', 'handsome']
const newArr = Array.from(arr)
arr[2] = 'rich' // 改变原来的数组
console.log(newArr) // ['lin', 'is', 'handsome']
- 4 扩展运算符
const arr = ['lin', 'is', 'handsome']
const newArr = [...arr]
arr[2] = 'rich' // 改变原来的数组
console.log(newArr) // ['lin', 'is', 'handsome'] // 新数组不变
const obj = {
name: 'lin'
}
const newObj = { ...obj }
obj.name = 'xxx' // 改变原来的对象
console.log(newObj) // { name: 'lin' } // 新对象不变
深拷贝
- 1 如果对象中没有方法可以简单的使用 JSON.prase(JSON.stringify)
- 2 如果对象中有方法 可以自己手写简单的克隆方法
function deepClone(obj) {
let objClone = obj instanceof Array ? [] : {};
if (obj && typeof (obj) === 'object') {
for (let key in obj) {
// 判断属性是否是在实例本身
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof (obj[key]) === 'object') {
objClone[key] = deepClone(obj[key])
} else {
objClone[key] = obj[key]
}
}
}
}
return objClone
}
let result = deepClone(origin)
console.log('result: ', result);
result.a[0] = [2, 2]
console.log(origin)
考虑的不是很全面,但是还是可以用的
- 3 如果对象 需要支持对象、数组、日期、正则的拷贝 可以考虑引入lodash cloneDeep 方法