[기본형과 참조형의 구분 기준]
- 복제의 방식
- 기본형 : 값이 담긴 주소값을 바로 복제
- 참조형 : 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제
- 불변성의 여부
- 기본형 : 불변성을 띔
- 참조형 : 불변성을 띄지 않음
cf) 불변하다는 것은 데이터 영역 메모리를 변경할 수 없음을 의미
var score;
score = 80;
score = 90;
// 할당이 이뤄지는 시점에 객체 리터럴이 해석되고, 그 결과 객체가 생성된다.
var person = {
name: 'Lee'
};
// person 변수에 저장되어 있는 참조 값으로 실제 객체에 접근한다.
console.log(person); // {name: 'Lee'}
// 프로퍼티 값 갱신
person.name = 'Kim';
// 프로퍼티 동적 생성
person.address = 'Seoul';
console.log(person); // {name: "Kim", address: "Seoul"}
var person = {
name: 'Lee'
};
// 참조 값을 복사(얕은 복사)
var copy = person;
var person = {
name: 'Lee'
};
// 참조 값을 복사(얕은 복사), copy와 person은 동일한 참조 값을 갖는다.
var copy = person;
// copy와 person은 동일한 객체를 참조한다.
console.log(copy === person); // true
// copy를 통해 객체를 변경한다.
copy.name = 'Kim';
// person을 통해 객체를 변경한다.
person.address = 'Seoul;
// copy와 person은 동일한 객체를 가리키기 때문에 서로 영향을 주고받는다.
console.log(person); // {name: "Kim", address: "Seoul"}
console.log(copy); // {name: "Kim", address: "Seoul"}
// user 객체를 생성
var user = {
name: 'hyewon',
gender: 'female',
};
// 객체의 프로퍼티에 접근하여 변경 -> 가변
var changeName = function (user, newName) {
var newUser = user;
newUser.name = newName;
return newUser;
};
var user2 = changeName(user, 'hyetwo');
if (user !== user2) {
console.log('유저 정보가 변경되었습니다.'); // 출력 X
}
console.log(user.name, user2.name); // hyetwo hyetwo
console.log(user === user2); // true
// user 객체를 생성
var user = {
name: 'hyewon',
gender: 'female',
};
// 새로운 객체를 반환 -> 불변
var changeName = function (user, newName) {
return {
name: newName,
gender: user.gender,
};
};
var user2 = changeName(user, 'hyetwo');
if (user !== user2) {
console.log('유저 정보가 변경되었습니다.'); // 출력 O
}
console.log(user.name, user2.name); // hyeone hyetwo
console.log(user === user2); // false
얕은 복사
의 방법이 있다.var copyObject = function (target) {
var result = {};
for (var prop in target) {
result[prop] = target[prop];
}
return result;
}
var user = {
name: 'hyewon',
gender: 'female',
};
var user2 = copyObject(user); // 1 depth copy (얕은 복사)
user2.name = 'hyetwo';
if (user !== user2) {
console.log('유저 정보가 변경되었습니다.');
}
console.log(user.name, user2.name); // hyewon hyetwo
console.log(user === user2); // false
얕은 복사
도 여전히 문제가 있다.var user = {
name: 'hyewon',
urls: {
portfolio: 'http://github.com/abc',
blog: 'http://blog.com',
facebook: 'http://facebook.com/abc',
}
};
var user2 = copyObject(user);
user2.name = 'hyetwo';
// 바로 아래 단계에 대해서는 불변성을 유지하기 때문에 값이 달라진다.
console.log(user.name === user2.name); // false
// 더 깊은 단계에 대해서는 불변성을 유지하지 못하기 때문에 값이 같다.
user.urls.portfolio = 'http://portfolio.com';
console.log(user.urls.portfolio === user2.urls.portfolio); // true
// 아래 예도 똑같아요.
user2.urls.blog = '';
console.log(user.urls.blog === user2.urls.blog); // true
var user = {
name: 'hyewon',
urls: {
portfolio: 'http://github.com/abc',
blog: 'http://blog.com',
facebook: 'http://facebook.com/abc',
}
};
var user2 = copyObject(user); // 1 depth copy
user2.urls = copyObject(user.urls); // 2 depth copy
user.urls.portfolio = 'http://portfolio.com';
console.log(user.urls.portfolio === user2.urls.portfolio); // false
user2.urls.blog = '';
console.log(user.urls.blog === user2.urls.blog); // false
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;
}