도서 코어자바스크립트를 읽고 준비한 발표자료를 블로그 글로 정리한다!
문제상황
let people1 = {
name : "A",
gender : "male",
age : 10,
... // 더 많은 프로퍼티가 있다고 가정
}
예를 들어 위와 같이 복잡한 데이터 구조를 가지는 people 객체가 존재한다.
그리고 이때 이름만 다르고 나머지 속성들은 모두 같은 people의 복제 객체가 3개가 더 필요하다면?
만약, 기존 객체를 이용하여 이름만 바꾸게 된다면?
const changeName = function(people, newName) {
let newPeople = people;
newPeople.name = newName;
return newPeople;
}
let people2 = changeName(people1, "B");
let people3 = changeName(people1, "C");
console.log(people1.name); // C
console.log(people2.name); // C
console.log(people3.name); // C
people1~3까지 모든 변수는 같은 주솟값을 바라보고, 그 주솟값 중 name 프로퍼티가 가리키는 데이터를 변경했기 때문에, 모든 변수에 담긴 name 프로퍼티 값이 변경된다.
문제 해결
문제 해결을 위해서는 윈본 객체 내부의 프로퍼티들을 복사한 새로운 객체를 생성하여 변수에 할당해주어야 한다.
const changeNum = function(people, newName) {
return {
name : newName,
gender : people.gender,
age : people.age,
key : people ... // 나머지 프로퍼티 등
}
}
people2 = changeName(people1, "B");
people3 = changeName(people1, "c");
console.log(people1.name); // A
console.log(people2.name); // B
console.log(people3.name); // C
→ 이러한 하드 코딩이 수고로우니 모든 프로퍼티를 복사하는 함수를 만드는 편이 낫겠다!
const copyObject = function(target) {
const newObject = {};
for (let prop in target) {
newObject[prop] = target[prop];
}
return newObject;
}
또한 이렇게 불변 객체를 만들어 변경을 방지하고, 변경이 필요한 경우에는 방어적 복사를 통해 새로운 객체를 생성한 후 기존 참조를 새로운 객체에 대한 참조로 완전히 갈아끼워주는 방식을 사용할 수 있다.
Object.assign
Spread operator
'Immutable.js' 라이브러리
const copyObject = function(target) {
let result = {};
for (const prop in target) {
result[prop] = target[prop];
}
return result;
};
let user = {
name: 'younghyun',
urls: {
github: 'http://github.com/younghyun',
blog: 'http://velog.io/@younghyun'
}
};
let user2 = copyObject(user);
user2.urls = copyObject(user.urls);
user2.name = 'jaewon';
console.log(user.name === user2.name); // false
user.urls.blog = 'https://medium.com/@jaewon';
console.log(user.urls.blog === user2.urls.blog); // false
user2.urls.github = '';
console.log(user.urls.github === user2.urls.github ); // false
const copyObjectDeep = function(target) {
let result = {};
if (typeof target === 'object' && target !== null) {
for (const prop in target) {
result[prop] = copyObjectDeep(target[prop]);
}
} else {
result = target;
}
return result;
};
let user = {
name: 'younghyun',
urls: {
github: 'http://github.com/younghyun',
blog: ['http://velog.io/@younghyun','https://medium.com/@younghyun']
}
};
let user2 = copyObjectDeep(user);
user2.name = 'jaewon';
console.log(user.name === user2.name); // false
user2.urls.blog[1] = 'https://steemit.com/@jaewon';
console.log(user.urls.blog[1] === user2.urls.blog[1]); // false
user2.urls.github = '';
console.log(user.urls.linkedin === user2.urls.linkedin); // false
console.log(user);
/*
{
name: 'younghyun',
urls: {
github: 'http://github.com/younghyun',
blog: ['http://velog.io/@younghyun','https://medium.com/@younghyun']
}
}
*/
console.log(user2);
/*
{
name: 'jaewon',
urls: {
github: '',
blog: {
'0': 'http://velog.io/@younghyun',
'1': 'https://steemit.com/@jaewon'
}
}
*/
const copyObjectViaJson = (target) => {
return JSON.parse(JSON.stringify(target));
};
// ... 중략
도서 코어자바스크립트
https://galid1.tistory.com/663