ECMAScript-浅拷贝和深拷贝
程序员文章站
2024-03-18 12:00:04
...
一、ECMAScript-浅拷贝和深拷贝
1. 概念
深拷贝:拷贝的对象是新的对象,跟原来的对象不存在共享属性。
浅拷贝:拷贝的对象只是引用原对象的属性。
图解:
我们现在有一个对象在内存中,
深拷贝:是两个完全独立的个体
浅拷贝:对象和函数部分只是引用
2. Object.assign()存在的问题
// Object.assign()常常被用来拷贝对象,但是这种拷贝只是简单的拷贝,不能进行深层次的拷贝,
// 原因:Object.assign()在进行复杂对象的拷贝的时候,只是把引用地址进行的替换,并没有真正的拷贝值
// 简单对象
let target = {
d: 2,
e: 3,
f: 4
}
let source = {
g: 4
}
Object.assign(target, source)
console.log(target) // {d: 2, e: 3, f: 4, g: 4} 正常
// 复杂对象
let target = {
a: {
b: {
c: 1
},
d: 2,
e: 3,
f: 4
}
}
let source = {
a: {
b: {
c: 1
},
d: 2,
e: 3
}
}
Object.assign(target, source)
console.log(JSON.stringify(target)) // {"a":{"b":{"c":1},"d":2,"e":3}} 丢失了f
// 拷贝出来的值,值改变两者都不影响,叫深拷贝
let a = 5
let b = a
a = 6
console.log(a, b) // 6 5
// 拷贝出来的值,值改变影响到另一个值,叫浅拷贝
let obj1 = {
name: 'zhangsan',
age: 30
}
let obj2 = obj1
console.log(JSON.stringify(obj1)) // {"name":"zhangsan","age":30}
obj1.name = 'lisi' // 改变obj1的值
console.log(JSON.stringify(obj2)) // {"name":"lisi","age":30} obj2的值却改变了
3. 其他拷贝也存在的问题
// 扩展符
const newObj = {...obj}
// Object.creact()
const newObj = Object.creact({},obj)
4. 怎么去实现一个深拷贝
// 方式一:缺陷:如果对象中存在方法则转化就会失败
// 通过JSON.stringify()和JSON.parse()
let obj1 = {
name: 'zhangsan',
age: 30,
study(){
console.log(this.name)
}
}
// 先通过JSON.stringify()将其转换成json格式的字符串
let str = JSON.stringify(obj1)
// 再转换成json对象
let obj2 = JSON.parse(str)
// 更改obj1属性的值
obj1.name = 'lisi'
console.log(obj2) // {name: "zhangsan", age: 30} 并未改变,但是方法丢失了
// 方式二:自己实现
let checkType = data => {
return Object.prototype.toString.call(data).slice(8, -1)
}
console.log(checkType(function(){
console.log('1111')
}))
let deepClone = target => {
let targetType = checkType(target)
let result
if (targetType === 'Object') {
result = {}
} else if (targetType === 'Array') {
result = []
} else{
return target
}
for(let key in target) {
let value = target[key]
let valueType = checkType(value)
if(valueType === 'Object' || valueType === 'Array'){
result[key] = deepClone(value)
} else if (valueType === 'Function') {
result[key] = target[key].bind(result)
} else {
result[key] = value
}
}
return result
}
// 验证一:
let arr1 = [1, 2, {age: 18}]
let arr2 = deepClone(arr1)
arr2[2].age = 40
console.log(arr1) // 互不影响
console.log(arr2)
// 验证二:
let obj1 = {
name: 'zhangsan',
age: 30,
study(){
console.log(this.name)
}
}
let obj2 = deepClone(obj1)
console.log(obj1)
obj1.name = 'lisi'
console.log(obj1.study === obj2.study) // fasle
上一篇: 对字符串进行匹配和替换系统
下一篇: 利用两个栈模拟队列操作