JS30 day14 Reference vs Copy
JS30 day14 - Reference vs Copy
作業內容
今天主要是在釐清 JS 裡面的基本型別 pass by value 跟 pass by reference 還有怎麼應對
學到什麼
- JS
- JS 裡面的數字 / 布林值 / 字串是 pass by value,但陣列跟 Object 是 pass by reference
// 數字 字串 布林值 let age = 100; let age2 = age; console.log(age, age2); // 100 100 age = 200; console.log(age, age2); // 200 100 // 陣列 const players = ['Wes', 'Sarah', 'Ryan', 'Poppy']; const team = players console.log(players, team) // (4) ["Wes", "Sarah", "Ryan", "Poppy"] (4) ["Wes", "Sarah", "Ryan", "Poppy"] team[3] = 'Lux' console.log(players, team) //(4) ["Wes", "Sarah", "Ryan", "Lux"] (4) ["Wes", "Sarah", "Ryan", "Lux"]- 陣列的 copy 方法
const team2 = players.slice() const team3 = [].concat(players) const team4 = [...players] //ES6 const team5 = Array.from(players)- Object 是最麻煩的,如果只有一層你可以使用
assign:
問題是 assgin 是淺拷貝,兩層以上會出現一樣的問題 (WTF moment)const person = { name: 'Wes Bos', age: 80 }; const cap2 = Object.assign({}, person, { number: 99, age: 12 }) console.log(person, cap2) //{name: "Wes Bos", age: 99} {name: "Wes Bos", age: 12, number: 99}
結果如下:const wes ={ name: 'Wes', age: 100, social: { twitter: 'wesbos', facebook: 'developer' } } const dev = Object.assign({}, wes) dev.social.twitter = "qoo" console.log(wes, dev)
他這裡有介紹一種深拷貝的方法,但效能不怎麼好:
這篇文章寫得很詳細可以參考: Object深拷貝的方法const dev2 = JSON.parse(JSON.stringify(wes));
參考資料: https://github.com/wesbos/JavaScript30
code 內容:
JS:
// 對於字串 / 數字 / 布林值來說是 pass by value
let age = 100;
let age2 = age;
console.log(age, age2); // 100 100
age = 200;
console.log(age, age2); // 200 100
// 對於陣列來說是 pass by reference
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
const team = players
console.log(players, team) // (4) ["Wes", "Sarah", "Ryan", "Poppy"] (4) ["Wes", "Sarah", "Ryan", "Poppy"]
team[3] = 'Lux'
console.log(players, team) //(4) ["Wes", "Sarah", "Ryan", "Lux"] (4) ["Wes", "Sarah", "Ryan", "Lux"]
// 解決方法:複製一份
const team2 = players.slice()
const team3 = [].concat(players)
// ES6 方法:打散
const team4 = [...players]
const team5 = Array.from(players)
// The same thing goes for objects, let's say we have a person object
// 對於 Object 來說也是 pass by reference
const person = {
name: 'Wes Bos',
age: 80
};
const captain = person
console.log(person, captain) // {name: "Wes Bos", age: 80} {name: "Wes Bos", age: 80}
captain.age = 99
console.log(person, captain) // {name: "Wes Bos", age: 99} {name: "Wes Bos", age: 99}
// 所以也要做個複製出來
const cap2 = Object.assign({}, person, { number: 99, age: 12 })
console.log(person, cap2) //{name: "Wes Bos", age: 99} {name: "Wes Bos", age: 12, number: 99}
// 然而這個 assign 方法是 shallow 的,如果有多層結構,還是會改到原本 Object
const wes ={
name: 'Wes',
age: 100,
social: {
twitter: 'wesbos',
facebook: 'developer'
}
}
const dev = Object.assign({}, wes)
dev.social.twitter = "qoo"
console.log(wes, dev)
//解決方法之一:
const dev2 = JSON.parse(JSON.stringify(wes));