JS30 Day 14 筆記


Posted by GL on 2023-05-25

目標

介紹 JavaScript 賦值時何時為複製(Copy)以及引用(refrence)。

Demo

step 1 : 原始型別(Call by value)

原始型別(String、Number、Boolean、Null、undefined、NaN),複製時為 Call by value

let age = 100;
let age2 = age;
console.log(age, age2); // 100 100
age = 200;
console.log(age, age2); // 200 100

let name = 'Wes';
let name2 = name;
console.log(name, name2); // Wes Wes
name = 'wesley';
console.log(name, name2); // wesley Wes

step 2 : 物件型別(Call by refrence)-陣列複製

物件型別(object、array)複製時為 Call by reference

// Let's say we have an array
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];

// and we want to make a copy of it.
const team = players; // team 與 palyers 指向同個記憶體位置(陣列['Wes', 'Sarah', 'Ryan', 'Poppy']),

console.log(players, team);

// team[3] 由於與 palyers 指向同個記憶體位置,所以 team[3] ="Lux" 時,players[3] 也同樣改變
team[3] = 'Lux';  // ["Wes", "Sarah", "Ryan", "Lux"] ["Wes", "Sarah", "Ryan", "Lux"]


// 複製時爲了避免因爲因 call by reference 改變到原有的陣列,有以下幾種複製方法
// slice will return a new array
const team2 = players.slice();

// or create a new array and concat the old one in
const team3 = [].concat(players);

// or use the new ES6 Spread
const team4 = [...players];

team4[3] = 'heeee hawww';
console.log(team4);

// or use Array.from()
const team5 = Array.from(players);

step 3 : 物件型別(Call by refrence)- 物件複製

// with Objects
const person = {
  name: 'Wes Bos',
  age: 80
};

// and think we make a copy:
const captain = person;
captain.number = 99;  // person = { name: 'Wes Bos',age: 99};


const cap2 = Object.assign({}, person, { number: 99, age: 12 });
console.log(cap2);  // Object {name: "Wes Bos", age: 12, number: 99}

// We will hopefully soon see the object ...spread
const cap3 = {...person};

// Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.

const wes = {
  name: 'Wes',
  age: 100,
  social: {
    twitter: '@wesbos',
    facebook: 'wesbos.developer'
  }
};

console.clear();
console.log(wes);

const dev = Object.assign({}, wes);

dev.age = 50;
dev.social.twitter = '@asdf111';

console.log('wes', wes); 
console.log('dev', dev); // wes 的 social 下的 twitter 的值為'@asdf111'

step 4 : JSON.parse(JSON.stringify())

當物件型別要複製到第二層時,先將陣列或物件變成 string 後在轉成 JSON 格式(需排除第二層有 function )

const dev2 = JSON.parse(JSON.stringify(wes));

參考資料:


#JS 30







Related Posts

JS 設定預設值 (Default Parameters)

JS 設定預設值 (Default Parameters)

OOP - 7 關於封裝

OOP - 7 關於封裝

關於 React 小書:ComponentWillMount, ComponentDidMount, ComponentWillUnmount

關於 React 小書:ComponentWillMount, ComponentDidMount, ComponentWillUnmount


Comments