[Javascript] Object.freeze()된 객체는 변경할 수 없을까?

벌써 우테코의 프리코스 4주차가 시작되었습니다. 저는 이전 미션에서 Objcet.freeze()에 대한 개념을 알게 되었는데요, 간단하게 Object.freeze()에 대해서 짚고 넘어가보겠습니다.

❓Object.freeze() 메서드의 기능

단어에서 알 수 있듯이, feeze 즉 객체를 동결하는 기능을 가졌습니다. 예시를 먼저 들어볼게요.

const obj = {
	name: "lurgi",
	age: 20,
}

obj.name = "jeong" //변경 가능
console.log(obj.name) //jeong

객체는 const 로 선언한다 하더라도, 키 값을 알면 수정이 가능한데요, 이 기능을 방지해주는 역할을 합니다

const obj = {
	name: "lurgi",
	age: 20,
}
Object.freeze(obj)

obj.name = "jeong" //변경 불가, 비엄격 모드에서는 조용하게 실
console.log(obj.name) //lurgi
//혹은
const obj = Object.freeze({
	name: "lurgi",
	age: 20,
})

이 기능을 이용하여, 데이터의 변경을 막을 수 있었습니다.

❓Objcet.freeze()를 하면 변경이 불가능할까?

하지만 이번 피드백에서 Object.freeze()기능이 만능이 아니라는 것을 알게 되었습니다.

이는 MDN 문서에도 잘 나와있는데요. 바로 이 기능은 “얕은 동결” 이라는 것입니다.

즉 객체가 2차원 배열 이상의 객체라면 변경이 가능하게 된다는 말이죠.

const obj = Object.freeze({
	lurgi : {
		name : "lurgi"
		age : "25"
	}
})

obj.lurgi.name = "jeong" //변경 가능

즉 객체 자체를 ‘불변’으로 만들 지 못했다는 것입니다.

❓그렇다면 깊은 동결, 불변으로 만들기 위해서는?

Object.freeze()로는 불변 객체를 만들 수 없다는 것을 알았습니다. 그렇다면 어떻게 불변으로 만들 수 있을까요?

MDN 문서에서는 재귀를 이용한 깊은 동결을 사용하는 deepFreeze() 메서드를 만들어서 사용하라고 합니다.

function deepFreeze(object){
	// getOwnPropertyNames: 배열일 경우 index를, 객체일 경우 key값을 배열로 받아온다
	const keys = Object.getOwnPropertyNames(object)
    
	for(const key of keys){
		const value = object[key]
		if(value && typeof value === "object"){
			object[key] = deepFreeze(value)
		}
	}

	return Object.freeze(object)
}

이렇게 deepFreeze 메서드를 Util 함수로 만들어서 Object.freeze() 대신 사용한다면, 내부의 자식 객체 역시 동결되므로 깊은 동결이 가능합니다. 즉 객체를 불변으로 만드는 것이 가능하겠네요!

😀결론!

Object.freeze() 메서드로 동결 시킬 경우, 객체가 2차원 이상의 객체인지 우선 확인하고, 내부 자식 요소에 객체가 있다면, deepFreeze() 메서드를 Util함수로 만들어서 사용해야 한다!

Object.freeze() - JavaScript | MDN