객체 내부의 객체를 상수값으로 변환deepFreeze

이한재·2023년 3월 2일
0

일반적으로 객체의 값을 상수화 시키는 함수가
Object.freeze() 라는 자바스크립트 기본 내장 함수가 있는데 인자로는 object 를 받고
리턴값으로 인자로 받은 object 를 반환한다.

code

const user = {
	name : "foo",
  	age : 30,
  	strength : 10,
  	agility : 10,
  	hp : 100,
  	mp : 100
}

Object.freeze(user)

위와 같은 user 객체가 있을 경우 Object.freeze() 함수를 사용하여 객체를 동결할 수 있는데 동결한다는 것은 객체를 상수화 한다는 의미라고 볼 수 있다.
즉 상수화 시키게 되면
객체의 프로퍼티의 값을 변경하는 것도 불가능해지고
객체의 프로퍼티를 추가하거나 객체의 프로퍼티를 삭제하는 것도 불가능 해진다.
즉 객체의 프로퍼티의 값을 읽는 것만 가능해진다.

이 Object.freeze 의 문제점은 객체 내부에 객체가 있을경우 안쪽에 있는 객체는 상수화가 안된다는 점에 있다.

예를 들면 다음과 같은 상황이다.

code

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)

output

{
  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() 가 적용되도록 할 수 있다.

deepFreeze function

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)
}

code

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)

output

{
  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 함수만 사용하였을때 와는 달리

객체 내부의 객체에 대해서도 값의 수정이 불가능하다는 점과
프로퍼티의 삭제가 불가능 하다는 것으로 보아
상수화가 적용된 것을 확인 할 수 있다.

profile
이한재입니다

0개의 댓글