참조(reference)와 복사(copy)의 차이점에 대해 알아본다.
배열이나 객체를 복사할 때 reference와 copy에 대해 혼동하기 쉽다. String과 Number는 대입만으로 복사할 수 있지만 Array와 Object는 그렇게 하면 복사가 아니라 참조를 하게 되는 것이 된다. 복사를 하려면 별도의 방법을 사용해야 한다.
const players = ['wes', 'sarah', 'ryan', 'poppy'];
const team = players;
console.log(players, team);
//players와 team이 똑같이 출력됨
team[3] = 'lux';
//team 뿐만 아니라 players까지 변경됨
team
은 배열이 아니라 team
이라는 변수로 players
라는 배열에 접근하는 것이다. 이는 복사가 아니라 참조라고 부른다. 따라서 team
과 players
는 독립적이지 않으며, team
으로 만든 변화들은 players
에도 적용된다.
원조 배열에 영향을 미치지 않으려면 참조가 아니라 복사를 해야하며, 배열의 복사는 다음과 같은 방법을 사용할 수 있다.
const team2 = players.slice();
const team3 = [].concat(players);
const team4 = [...players];
const team5 = Array.from(players);
const person = {
name: 'wes bos',
age: 80
};
const cap = person;
객체에서도 마찬가지이다. cap
은 객체가 아니라, 객체 person
을 참조하는 것이다.
객체를 복사하는 방법은 다음과 같은 방법들이 있다.
const cap2 = Object.assign({}, person);
const cap3 = Object.assign({}, person, {추가Key: 추가Value});
const cap4 = {...person};
Object.assign
에 여러 배열을 추가할 경우, 뒷 배열이 앞의 배열을 덮어쓰기 한다.Object.assign
에는 여러개의 배열을 전달할 수 있다.
이때, 뒷 배열의 key가 앞의 배열의 key로 이미 있다면, 뒷 배열의 value로 덮어쓰기 한다.
const person = {
name: 'wes bos'
};
const worker = {
name: 'some',
age: 20
};
const mixed = Object.assign({}, person, worker);
console.log(mixed.name); // some 출력됨
console.log(mixed.age); // 20 출력됨
Object.assign
은 오직 한 레벨만 복사한다.const wes = {
name: 'wes',
age: '90',
social:{
twitter: 'a',
facebook: 'b'
}
};
const copy = Object.assign({}, wes);
copy
를 가지고 name, age를 변경할 수 있고 이때 오리지널 객체인 wes
에는 영향을 주지 않는다.
그러나 만약 copy.social.twitter = 'c';
라고 업데이트를 하면,
copy.social.twitter
뿐만 아니라 wes.social.twitter
의 value까지 업데이트가 된다.
그 이유는 Object.assign
은 2레벨인 social
까지는 복사하지 않기 때문이다.
이 때에는 다음과 같이 JSON
을 사용하여 한 레벨 이상을 복사할 수 있는데, wesbos는 그닥 추천하지 않는 방법이라고 함.
const copy2 = JSON.parse(JSON.stringfy(wes));