객체는 참조(reference) 형태로 전달하고 전달 받음.
객체가 참조를 통해 공유되고 있다면, 그 상태가 언제든지 변경될 수 있기 때문에 의도치 않은 변경이 발생되어 여러가지 문제가 발생 될 수 있음.
의도하지 않은 객체의 변경이 발생하는 원인의 대다수는 "레퍼런스를 참조한 다른 객체에서 객체를 변경"하기 때문.
객체를 불변객체로 만들어 프로퍼티의 변경을 방지하여 객체의 변경이 필요한 경우에는 참조가 아닌 객체의 방어적 복사를 통해, 새로운 객체를 생성 후 변경
또는, Observer 패턴으로 객체의 변경에 대처.
1. immutable value vs. mutable value
- Boolean
- null
- undefined
- Number
- String
- Symbol (ECMAScript 6)
var text = 'Hello';
text = 'Bye';
console.log(text);
첫번째 구문이 실행되면, 메모리에 문자열 'Hello'가 생성, 식별자 text는 메모리에 생성된 문자열 'Hello'의 메모리 주소를 가르킴.
그리고 두번째 구문이 실행되면 이전에 생성된 'Hello' 문자열을 수정하는 것이 아닌, 새로운 문자열 'Bye'를 생성 후, 식별자 text가 가르키게 됨.
문자열 'Hello'와 'Bye'는 모두 메모리에 존재하는 상태가 됨.
var user = {
name: 'A',
address: {
city:'seoul'
}
};
var names = user.name; // A 할당
user.name = 'B';
console.log(typeof(names)); // String
console.log(names); // A
console.log(user.name); // B
user.name을 변경하였으나, 변수 names의 값은 변경되지 않음.
변수 names 에 user.name을 할당할때, 참조를 할당하는 것이 아닌, String의 immutable한 값이 새로 생성되었고, 해당 값을 참조하기 때문.
var user = {
name: 'A',
address: {
city:'seoul'
}
};
var user1 = user; // user Object
user1.name = 'B';
console.log(user.name);
console.log(user1.name);
user2의 name의 프로퍼티에 새로운 값을 할당하면 객체는 변경 가능한 값이므로, user 객체도 변경 됨.
이는 같은 address를 참조하고 있기 때문.
의도하지 않은 동작이라면 참조를 가지고 있는 다른 장소에 변경 사실을 통지 또는 대처하는 추가 대응이 필요.
2. 불변 데이터 패턴 (immutable data pattern)
2.1 Object.assign
var user = {
name: 'A',
address: {
city:'seoul'
}
};
const user1 = Object.assign({}, user); //user 객체를 user1에 저장.
console.log (user1 == user); //false
2.2 Object.freeze
var user = {
name: 'A',
address: {
city:'seoul'
}
};
Object.freeze(user);
user.name = 'B'; // 무시
console.log(user);
uesr.address.city = 'Daejeon';
console.log(user.address.city); //객체의 내부 객체는 변경 가능함.
내부 객체까지 변경 불가능하게 만들기 위해서는 Deep Freeze를 해야 함.
function deepFreeze(object) {
var propNames = Object.getOwnPropertyNames(object); // 객체의 key를 propNames에 배열로 저장
for (let name of propNames) { // 배열의 length만큼 반복
let value = object[name];
object[name] = value && typeof value === "object" ?
deepFreeze(value) : value;
}
return Object.freeze(object);
}
var user = {
name: 'A',
address: {
city:'seoul'
}
};
deepFreeze(user);
'4. Programming > 4.3 JavaScript' 카테고리의 다른 글
8. 타입 체크 (0) | 2018.07.24 |
---|---|
7. Function (함수) (0) | 2018.07.15 |
5. Object (객체) (0) | 2018.06.17 |
4. 제어문 (Control flow statement) (0) | 2018.05.28 |
3. Operator (연산자) (0) | 2018.05.12 |