ES6 對象解構賦值(為深拷貝還是淺拷貝)


對象的擴展運算符(...)用於取出參數對象的所有可遍歷屬性,拷貝到當前對象之中。

拷貝對象

let aa = {
    age: 18,
    name: 'aaa'
}

 
let bb = {...aa};
console.log(bb);  // {age: 18, name: "aaa"}

合並對象

擴展運算符(...)可以用於合並兩個對象

let aa = {
    age: 18,
    name: 'aaa'
} 

let bb = {
    sex: '男'
}
  
let cc = {...aa, ...bb}; 


// 等同於: 
// let cc = Object.assign({}, aa, bb);


console.log(cc); // {age: 18, name: "aaa", sex: "男"}

拷貝並修改對象

在擴展運算符后面,加上自定義的屬性,則擴展運算符內部的同名屬性會被覆蓋掉。

let aa = {
    age: 18,
    name: 'aaa'
}
 
let dd = {...aa, name: 'ddd'};
 

// 等同於: 
// let dd = {...aa, ...{name: 'ddd'}};
// let dd = Object.assign({}, aa, { name: 'ddd'});



console.log(dd); // {age: 18, name: "ddd"}

一般,在 redux 中修改 state 時,會用解構賦值的方法。

但是,解構后得到的新對象,相對於老對象,是淺拷貝,還是深拷貝?

例如,下面肯定是引用賦值:

let aa = {
    age: 18,
    name: 'aaa'
}

let bb = aa;
bb.age = 22;

console.log(aa.age); // 22

上面, 對象 bb 是 aa 的一個引用賦值。那么,如果使用解構賦值得到 bb 呢:

let aa = {
    age: 18,
    name: 'aaa'
}

let bb = {...aa};
bb.age = 22;

console.log(aa.age); // 18
  • 可見,改變 bb 的屬性 age 的值,並不會改變對象 aa 的屬性的 age 的值,所以,上面的例子bb是aa的一份拷貝
  • 但是,這個拷貝是只有一層的淺拷貝,還是深拷貝?
    let aa = {
        age: 18,
        name: 'aaa',
        address: {
            city: 'shanghai'
        }
    }
    
    let bb = {...aa};
    bb.address.city = 'shenzhen';
    
    console.log(aa.address.city);  // shenzhen

    可見,aa 解構賦值到新對象 bb,只是進行了一層淺拷貝,對象 bb 中的屬性(address)的屬性(city)還是對象 aa 中屬性的屬性的引用。

    如果像拷貝 aa 中的 city 屬性,可以像下面處理:

    let aa = {
        age: 18,
        name: 'aaa',
        address: {
            city: 'shanghai'
        }
    }
    
    let bb = {
        ...aa,
        address: {...aa.address}
    };
    
    bb.address.city = 'shenzhen';
    
    console.log(aa.address.city);  // shanghai

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM