일반적으로 객체의 값을 상수화 시키는 함수가
Object.freeze() 라는 자바스크립트 기본 내장 함수가 있는데 인자로는 object 를 받고
리턴값으로 인자로 받은 object 를 반환한다.
const user = {
name : "foo",
age : 30,
strength : 10,
agility : 10,
hp : 100,
mp : 100
}
Object.freeze(user)
위와 같은 user 객체가 있을 경우 Object.freeze() 함수를 사용하여 객체를 동결할 수 있는데 동결한다는 것은 객체를 상수화 한다는 의미라고 볼 수 있다.
즉 상수화 시키게 되면
객체의 프로퍼티의 값을 변경하는 것도 불가능해지고
객체의 프로퍼티를 추가하거나 객체의 프로퍼티를 삭제하는 것도 불가능 해진다.
즉 객체의 프로퍼티의 값을 읽는 것만 가능해진다.
이 Object.freeze 의 문제점은 객체 내부에 객체가 있을경우 안쪽에 있는 객체는 상수화가 안된다는 점에 있다.
예를 들면 다음과 같은 상황이다.
const user = {
name : 'hanjae',
age : '30',
strength: 10,
agility : 10,
hp : 100,
mp : 100,
items : {
weapon : "sword",
armor : "plate armor",
accessories : {
rings : "normal ring",
earring : "normal earring"
}
}
}
Object.freeze(user)
user.items.weapon = "normal sword"
delete user.items.armor
console.log(user)
{
name: 'hanjae',
age: '30',
strength: 10,
agility: 10,
hp: 100,
mp: 100,
items: {
weapon: 'normal sword',
accessories: { rings: 'normal ring', earring: 'normal earring' }
}
}
위 처럼 user 내부의 객체가 있고 그 내부에 또 다른 객체가 있다고 하였을 경우
객체 전부를 상수화 시키려면
user 뿐만 아니라 user.itmes, user.items.accessories 또한 Object.freeze 를 호출해서 상수화 해주어야 한다.
따라서 객체 내부의 객체에 대해서는 상수화가 적용이 되지 않았기 때문에 프로퍼티의 값을 수정할 수도 있고
delete 키워드를 이용해 프로퍼티를 삭제 할 수도 있게된다.
이러한 문제점을 해결하기 위해서는
객체 내부의 모든 프로퍼티의 값을 가져오고 값이 만약 object 타입 일때 재귀적으로 함수를 호출하여 객체 안에 객체까지 Object.freeze() 가 적용되도록 할 수 있다.
const deepFreeze = (obj) => {
const propNames = Object.getOwnPropertyNames(obj)
for (let name of propNames) {
const value = obj[name]
if (typeof value == 'object') {
deepFreeze(value)
}
}
return Object.freeze(obj)
}
const user = {
name : 'hanjae',
age : '30',
strength: 10,
agility : 10,
hp : 100,
mp : 100,
items : {
weapon : "sword",
armor : "plate armor",
accessories : {
rings : "normal ring",
earring : "normal earring"
}
}
}
deepFreeze(user)
user.items.weapon = "normal sword"
delete user.items.armor
console.log(user)
{
name: 'hanjae',
age: '30',
strength: 10,
agility: 10,
hp: 100,
mp: 100,
items: {
weapon: 'sword', // 수정 X
armor: 'plate armor', // 삭제 X
accessories: { rings: 'normal ring', earring: 'normal earring' }
}
}
deepFreeze 함수를 적용하였을 때 Object.freeze 함수만 사용하였을때 와는 달리
객체 내부의 객체에 대해서도 값의 수정이 불가능하다는 점과
프로퍼티의 삭제가 불가능 하다는 것으로 보아
상수화가 적용된 것을 확인 할 수 있다.