1. 程式人生 > 其它 >ES6深拷貝與淺拷貝

ES6深拷貝與淺拷貝

今天小編和大家一起探討js中深拷貝和淺拷貝,簡單一點理解就是,對於引用資料型別,深拷貝是資料引用地址不同,在改變一個數據的時候,不會影響另一個數據。而淺拷貝剛好相反。兩個資料引用的是同一個堆記憶體地址,一個數據改變的時候,會影響另一個相關的資料。

在之前的章節中,小編提起過關於物件的複製的方法,Object.assign(),但是這個方法只是針對物件的淺拷貝。大家也可以關注我的微信公眾號,蝸牛全棧。

let target = {}
let source = {
    a:1,
    b:2
}
Object.assign(target,source)
console.log(target) 
// {a:1,b:2}
let target = {}
let source = {
    a:{
        b:{
            c:1
        }
    },
    e:2,
    f:3
}
Object.assign(target,source)
console.log(target) // {a:{b:{c:1}},e:2,f:3}
let target = {
    a:{
        b:{
            c:1
        }
    },
    e:4,
    f:5,
    g:6
}
let source = {
    a:{
        b:{
            c:
1 } }, e:2, f:3 } Object.assign(target,source) console.log(target) // {a:{b:{c:1}},e:2,f:3} // 這裡面沒有將target中的g屬性和值

深拷貝(基本資料型別)

let a = 5
let b = a
a = 6
console.log(a,b) // 6 5

淺拷貝(物件,兩個資料相互影響。一個數據內容改變之後會影響另一個數據)

let obj1 = {
    name:"lilei",
    age:18
}
let obj2 = obj1
console.log(obj1) 
// {name:"lilei",age:18} console.log(obj2) // {name:"lilei",age:18} obj1.age = 30 console.log(obj1) // {name:"lilei",age:30} console.log(obj2) // {name:"lilei",age:30}

深拷貝(物件)

方式一:

let obj1 = {
    name:"lilei",
    age:18
}

let str = JSON.stringify(obj1)
let obj2 = JSON.parse(str)

console.log(obj1) // {name:"lilei",age:18}
console.log(obj2) // {name:"lilei",age:18}
obj1.age = 30
console.log(obj1) // {name:"lilei",age:30}
console.log(obj2) // {name:"lilei",age:18}

方式二:

// 判斷資料型別
let checkType = data => {
    let t = Object.prototype.toString.call(data).slice(8,-1)
    return t
}
// 只考慮物件和陣列還有基本資料型別的深拷貝
let deepClone = target => {
    let targetType  = checkType(target)
    let result
    if(targetType === "Object"){
        result = {}
    }else if(targetType === "Array"){
        result = []
    }else{
        return target
    }
    for(let i in target){
        let value = target[i] // 每個屬性對應的值
        // 相容引用資料型別中還存在引用資料型別的情況
        let valueType = checkType(value)
        if(valueType === "Object" || valueType === "Array"){
            result[i] = deepClone(value) // 遞迴
        }else{
            result[i] = value
        }
    }
    return result
}

附加:

一、JSON:JSON本質就是字串,物件鍵不用引號,JSON需要用引號

JSON.stringify(obj)  // 將物件轉換成JSON格式字串
JSON.parse(obj) // 將JSON字串轉換成物件

二、typeof只能判斷基本資料型別,不能判斷引用資料型別,比如物件和陣列,返回的都是Object。可以用以下方式處理

let checkType = data => {
    let t = Object.prototype.toString.call(data)
    // let t = Object.prototype.toString.call(data).slice(8,-1) 擷取對應資料型別,比如Object和Array
    console.log(t)
}
checkType({}) // [Object Object]
checkType([]) // [Object Array]