본 포스팅은 코어 자바스크립트 책을 읽고 정리한 내용입니다.
예시
var user = {
name : 'jjg',
gemder : 'male'
};
var changename = function (user, newName)
{
var newUser = user;
newUser.name = newName;
return newUser;
};
var user2 = changeName(user, 'Jung');
console.log(user1.name,user2.name); // output : Jung Jung
console.log(user === user2); // output : true
위의 상황은 복사한 객체에 값을 변경하였지만, 원본 값도 같이 변경된걸 볼 수 있는데, 그 이유는 user1, user2 변수 모두 같은 주소공간을 바라보고 있고, 그 주소 공간 중 프로퍼티 name이 가리키는 데이터를 변경하였기 때문에, user1 user2의 값이 같이 변경된 문제가 생겨버렸다. 이 경우를 대비하기 위해서는 복사한 객체를 변경하더라도 원본 객체는 그대로여야하는 경우가 필요한데, 그렇기 위해서는 불변객체가 필요하다.
var user = {
name : 'JJG',
gender: 'male'
};
var changeName = fucntion(user, newName) {
return {
name : newName,
gender : user.gender
};
};
var user2 = changeName(user, 'kang');
console.log(user.name,user2.name); // output : JJG kang
console.log(user === user2.name); // output : false
단점. 복사하는 대상 객체에 정보가 많거나, 변경해야 할 정보가 많을수록 해야될 수고가 늘어난다.
var copyObject = function(target) {
var result = {};
for (var prop in target) {
result[prop] = target[prop];
}
return result;
}
var user = {
name : 'JJG',
gender: 'male'
};
var user2 = copyObject(user);
user2.name = "Kang";
console.log(user.name,user2.name); // output : JJG kang
console.log(user === user2.name); // output : false
단점. 바로 아래 단계의 값만 복사하여, 복사하는 대상이 중첩된 객체의 하위 프로퍼티일때, 사본 데이터를 변경할 시 원본 데이터도 똑같이 변경되는 상황이 생길 수 있음.
var user = {
name : 'JJG',
id : {
home : 'seoul'
}
};
var user2 = copyObject(user);
user2.name = 'Kang';
console.log(user.name === user2.name); // output : false
user2.id.home = 'none';
console.log(user.id.home === user2.id.home); // output : true
user객체에 직접 속한 프로퍼티에 대해서는 복사해서 완전히 새로운 데이터가 만들어진 반면, 하위 프로퍼티 id에서는 기존 데이터를 그대로 참조하기 때문에 원본, 사본 데이터가 똑같이 변경된것을 볼 수 있다. 이런 현상이 발생하지 않게 하려면 하위 프로퍼티들도 불변 객체로 만들어야한다
var copyObjectDeep = function(target) {
var result = {};
if (typeof target === 'object' && target !== null)
{
for (var prop in target)
{
result[prop] = copyObjectDeep(target[prop]);
}
}
else {
result = target;
}
return result;
}
var obj = {
a : 1,
b {
c : null,
}
};
var obj2 = copyObjectDeep(obj);
obj2.a.c = 3;
console.log(obj) // output : a :1 b : { c : null }
console.log(obj2) // output : a :1 b : { c : 4 }
(단, 메서드, 숨겨진 프로퍼티, getter/setter와 같이 json으로 변경할 수 없는 프로퍼티는 불가능)
『코어 자바스크립트』 (정재남, 위키북스)