ECMAScript-淺拷貝和深拷貝
一、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
相關文章
- 淺拷貝和深拷貝
- 深拷貝和淺拷貝
- iOS深拷貝和淺拷貝iOS
- js 深拷貝和淺拷貝JS
- JavaScript淺拷貝和深拷貝JavaScript
- Java深拷貝和淺拷貝Java
- 物件深拷貝和淺拷貝物件
- JavaScript深拷貝和淺拷貝JavaScript
- js 淺拷貝和深拷貝JS
- 淺拷貝&深拷貝
- python 指標拷貝,淺拷貝和深拷貝Python指標
- 淺探js深拷貝和淺拷貝JS
- go slice深拷貝和淺拷貝Go
- js之淺拷貝和深拷貝JS
- C++淺拷貝和深拷貝C++
- 深度解析深拷貝和淺拷貝
- JavaScript之深拷貝和淺拷貝JavaScript
- js的深拷貝和淺拷貝JS
- 聊聊物件深拷貝和淺拷貝物件
- java深克隆(深拷貝)和淺克隆(淺拷貝)Java
- 淺拷貝與深拷貝
- 淺談深拷貝與淺拷貝?深拷貝幾種方法。
- js實現深拷貝和淺拷貝JS
- VUE 中 的深拷貝和淺拷貝Vue
- 對淺拷貝和深拷貝的理解
- JS深拷貝與淺拷貝JS
- python深拷貝與淺拷貝Python
- Python淺拷貝與深拷貝Python
- javascript 淺拷貝VS深拷貝JavaScript
- 淺談Java中的淺拷貝和深拷貝Java
- 深入淺出深拷貝與淺拷貝
- Javascript知識點:淺拷貝和深拷貝JavaScript
- javaScript深拷貝和淺拷貝簡單梳理JavaScript
- 【Python】直接賦值,深拷貝和淺拷貝Python賦值
- Python擴充套件_淺拷貝和深拷貝Python套件
- js 陣列的淺拷貝和深拷貝JS陣列
- [JS系列二]談談深拷貝和淺拷貝,如何實現深拷貝JS
- 深拷貝、淺拷貝與Cloneable介面