Reference and Copy

By Value: Number, String, Boolean

Number

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

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

String

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

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

Boolean

let isGood=true;
let isGood2=isGood;
console.log(isGood, isGood2); //true true

isGood=false;
console.log(isGood, isGood2); //false true

By Reference: Object, Array, Function

const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
const team = players;
console.log(players, team);
// ["Wes", "Sarah", "Ryan", "Poppy"]
// ["Wes", "Sarah", "Ryan", "Poppy"]

team[3]='Luis';
console.log(players, team);
// ["Wes", "Sarah", "Ryan", "Luis"]
// ["Wes", "Sarah", "Ryan", "Luis"]

//teams[3]的「team」是Reference,所以初始一但被更新,複製的也會被更新

Reference中的例外:該如何讓被複製的array不受初始變更的影響

方法1:slice

const fruits=['apple', 'banana', 'orange', 'grape'];
const fruits2=fruits.slice();

fruits[3]='mango';
console.log(fruits, fruits2);
// ["apple", "banana", "orange", "mango"]
// ["apple", "banana", "orange", "grape"]

方法2:New Array+contact

const fruits=['apple', 'banana', 'orange', 'grape'];
const fruits3=[].concat(fruits);

fruits[3]='mango';
console.log(fruits, fruits3);
// ["apple", "banana", "orange", "mango"]
// ["apple", "banana", "orange", "grape"]

方法3:ES6 Spread

const fruits=['apple', 'banana', 'orange', 'grape'];
const fruits4=[...fruits];

fruits[3]='mango';
console.log(fruits, fruits4);
// ["apple", "banana", "orange", "mango"]
// ["apple", "banana", "orange", "grape"]

方法4:Array.from

const fruits=['apple', 'banana', 'orange', 'grape'];
const fruits5=Array.from(fruits);

fruits[3]='mango';
console.log(fruits, fruits5);
// ["apple", "banana", "orange", "mango"]
// ["apple", "banana", "orange", "grape"]

多層物件中的淺拷貝

當1個物件他有很多層時

透過assign改第1層:不會改到初始物件

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

const dev=Object.assign({}, wes);
dev.name='wesley';
console.log(wes, dev);
// Object {
//   name: 'wes',
//   age: 100,
//   social: {
//    twitter: '@webos',
//    facebook: 'wesbos.developer'
//  }
// }
// Object {
//   name: 'wesley',
//   age: 100,
//   social: {
//    twitter: '@webos',
//    facebook: 'wesbos.developer'
//  }
// }

透過assign改第2層:會一起改到初始物件

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

const dev2=Object.assign({}, wes);
console.log(wes, dev);
// Object {
//   name: 'wesley',
//   age: 100,
//   social: {
//    twitter: '@coolman',
//    facebook: 'wesbos.developer'
//  }
// }
// Object {
//   name: 'wesley',
//   age: 100,
//   social: {
//    twitter: '@coolman',
//    facebook: 'wesbos.developer'
//  }
// }

原因:assign指能對第1層做深拷貝,其他第2層以下還是淺拷貝

多層物件的多重深拷貝(clone deep)

使用這招前請三思是否有必要多重深拷貝

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

const dev3=JSON.parse(JSON.stringify(wes));
dev3.social.twitter='@coolman';
console.log(wes, dev3);
// Object {
//   name: 'wesley',
//   age: 100,
//   social: {
//    twitter: '@wesbos',
//    facebook: 'wesbos.developer'
//  }
// }
// Object {
//   name: 'wesley',
//   age: 100,
//   social: {
//    twitter: '@coolman',
//    facebook: 'wesbos.developer'
//  }
// }