두번째 공부(개발공부)/JavaScript DeepDive

TIL] 프로퍼티 어트리뷰트

YTReeee 2023. 6. 6. 17:42

프로퍼티 어트리뷰트?

자바스크립트 엔진이 관리하는 내부 상태 값(meta-property)인 내부슬롯 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]이다.

개발자가 내부슬롯에 직접 접근할 수 있는 방법은 없다. 단, Object.getOwnPropertyDescriptor(객체의 참조, '프로퍼티 키') 메서드로 간접 접근이 가능하다.

Object.getOwnPropertyDescriptors(객체의 참조) 메서드는 전달받은 인자인 객체의 모든 프로퍼티 키를 조회한다.


데이터프로퍼티

키와 값으로 구성된 일반적 프로퍼티이다.

[[Value]], [[Writable]], [[Enumerable]], [[Configurable]] << 데이터 프로퍼티이다.

[[Value]] : 프로퍼티의 값이며, 이외에 나머지 프로퍼티는 true로 초기화된다(프로퍼티를 동적으로 추가해도 동일하다.).


[[Writable]], [[Enumerable]], [[Configurable]] 값이 false인 경우는 아래와 같다.

[[Writable]] : value 값은 변경 불가능한 값이 되어 읽기전용 프로퍼티가 된다.

[[Enumerable]] : for... in문이나 Object.keys 메서드 등으로 열거할 수 없다.

[[Configurable]] : 프로퍼티 삭제, 어트리뷰트 값의 변경이 금지된다. 단, [[Writable]]이 true면 [[Value]]의 변경과, [[Writable]]을 false로 변경하는 것은 허용된다.


접근자 프로퍼티

자체적으로는 값을 갖지 않고, 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티이다.

[[Get]], [[Set]], [[Enumerable]], [[Configurable]] << 접근자 프로퍼티 이다.

[[Get]] : 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수이다. getter 함수가 호출되어 그 결과가 프로퍼티 값으로 반환된다.

[[Set]] : 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수이다. setter 함수가 호출되고, 그 결과가 프로퍼티 값으로 저장된다.


데이터 프로퍼티와 접근자 프로퍼티 구별 방법

일반 객체의 '__proto__'는 접근자 프로퍼티, 함수객체의 'prototype'은 데이터 프로퍼티


프로퍼티 정의(Object.defineProperty(객체의 참조, '프로퍼티 키', {프로퍼티 디스크립터 객체})

새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것을 말한다.


데이터 프로퍼티 정의

defineProperty함수에 프로퍼티 어트리뷰트를 별도 정의하지 않으면, false가 기본값

  • 'age' 프로퍼티는 열거가 불가능하기 때문에 Object.keys(dog) 메서드로 열거가 불가능하다.
  • 'age' 프로퍼티는 값을 수정할 수도 없기 때문에 새로운 값을 전달하거나 삭제가 불가능하다.

접근자 프로퍼티 정의

'age' 프로퍼티 어트리뷰트가 정의되지 않아, 기본값이 false가 적용되어, 마지막 줄의 'age'프로퍼티 값이 변경되지 않았다.


변경방지 메서드

구분 메서드 프로퍼티
추가
프로퍼티
삭제
프로퍼티
값 읽기
프로퍼티
값 쓰기
프로퍼티
어트리뷰트
재정의
객체 확장 금지 Object.preventExtensions X O O O O
객체 밀봉 Object.seal X X O O X
객체 동결 Object.freeze X X O X X
  • Object.isExtensions, Object.isSeal, Object.isFrozen // 불리언 값으로 가능여부를 리턴한다.
  • 위의 변경방지 메서드는 얕은 변경방지로 직속 프로퍼티만 변경이 방지된다.

불변객체

  • 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 Object.freeze 메서드를 호출해야 한다.

중첩객체 address도 동결되어 재할당 값이 적용되지 않고, 무시되었다.


회고

이번 챕터에서는 객체의 프로퍼티에 대해 공부하였다.

프로퍼티 어트리뷰트는 데이터 프로퍼티와 접근자 프로퍼티로 구분된다.

프로퍼티는 기본값을 갖지만, 명시적 정의를 통해 정의할 수 있다.

이를 통해 변경되면 안되는 값을 보호할 수 있다.

객체를 전반적으로 보호하기 위해서는 변경방지 메서드를 이용할 수 있다.

단, 변경방지 메서드는 얕은 방지만 가능하다.

이에 중첩된 객체까지 변경을 방지하기 위해서는 객체를 값으로 갖는 모든 프로퍼티에 동결 메서드를 적용해줘야 한다.

 

제대로 이해한 건지는 모르겠지만, 다시 보면서 정리를 하고나니 어떤 내용에 대해 공부했는지 알게된 것 같다.

앞으로 블로깅을 할 때는 단순히 쓰고 넘기는 것이 아니라 위에 써 있는 내용이더라도 한번 더 써보면서 요약을 해봐야겠다.


내용출처 : 모던 자바스크립트 Deep Dive, 이웅모 저