Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

과거의 내가 미래의 나에게

딥다이브 :: property attribute 본문

js 이론

딥다이브 :: property attribute

양바삭 2023. 2. 1. 12:57

「딥다이브 자바스크립트」 정리 - 프로퍼티 어트리뷰트

※ 아래 내용은 책을 통해 학습한 것을 개인적으로 정리한 것으로 내용이 다소 부정확 할 수 있습니다.

 


 

먼저 내부슬롯과 내부 메서드에 대해서

내부 슬롯과 내부 메서드는 js 엔진 내부에서만 사용하는 의사 프로퍼티와 의사 메서드이다. 이는 js 엔진 내에서 돌아갈 뿐  개발자가 직접 접근할 수 있는 객체의 프로퍼티는 아니다

하지만 일부에 한하여 간접적으로 접근할 수 있는 수단을 제공하기도 한다. 예를 들어 모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖는데, 원칙적으로 직접 접근할 수는 없지만 __proto__를 통해 간접적으로 접근할 수 있다.

참고로, ECMAScript 사양에 등장하는 이중 대괄호로 감싼 이름들이 내부 슬롯과 내부 메서드이다.

 

property attribute와 property descriptor 객체

js 엔진은 프로퍼티를 생성할 때, 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰티를 기본값으로 자동 정의하는데, 는 아래와 같은 내부 슬롯으로 이루어져있다. 

  • [[Value]] : 프로퍼티의 값
  • [[Writable]] : 값의 갱신 가능 여부
  • [[Enumerable]] : 열거 가능 여부
  • [[Configureable]] : 재정의 가능 여부

내부 슬롯이기에 직접 접근할 수는 없지만 간접적으로는 확인할 수 있는데 Object.getOwnPropertyDescriptor 메서드를 사용하면 된다.

Object.getOwnPropertyDescriptor(객체의 참조 전달, 프로퍼티 키를 문자열로 전달)로 호출하며, 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다. 만약 존재하지 않는 것을 요구하면 undefined를 반환한다.

let test = {name: 'yang'};
let res = Object.getOwnPropertyDescriptor(test,'name');
console.log(res);
//{
//  configurable: true,
//  enumerable: true,
//  value: "yang",
//  writable: true
//}

위 메서드는 하나의 프로퍼티에 대해서만 반환하지만 ES8부터 도입된 Object.getOwnPropertyDescriptors는 모든 프로퍼티의 프로퍼티 디스크립터 객체들을 반환한다.

 

데이터 property와 접근자 property

프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있다. 이는 Object.getOwnPropertyDescriptors를 하여 나온 반환값이 무엇인지에 따라 구별가능하다.

1. 데이터 프로퍼티

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

데이터 프로퍼티는 [[Value]],[[Writable]],[[Enumerable]],[[Configureable]] 이 4개의 프로퍼티 어트리뷰트를 갖는다.

  • Value: 프로퍼티 키를 통해 값에 접근하면 반환되는 값
  • writable: 프로퍼티 값의 변경 여부. false인 경우 value 값을 변경할 수 없게 된다. 값을 변경하려하면 에러는 발생하지 않고 무시할뿐이다.
  • enumerable: 프로퍼티 열거 가능 여부. false인 경우 forin문이나 Object.Keys 메서드 등으로 열거할 수 없게 된다.
  • configurable:프로퍼티 재정의 가능 여부. false일 시 해당 프로퍼티의 삭제, 프로퍼티 어트리뷰트 값의 변경이 금지된다. 단, writable이 true이면 value 변경과 writable을 false로 변경하는 것은 가능하다.

2. 접근자 프로퍼티

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

접근자 프로퍼티는 [[Get]],[[Set]],[[Enumerable]],[[Configurable]] 이 4개의 프로퍼티 어트리뷰트를 갖는다.

  • get: 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수이다. 접근자 프로퍼티 키로 프로퍼티 값에 접근하면 프로퍼티 어트리뷰트 Get의 값인 getter 함수가 호출되고 그 결과가 프로퍼티 값으로 반환된다.
  • set: 접근자 프로퍼티를 통해 데이터 프로퍼티 값을 저장할 때 호출되는 접근자 함수이다. 접근자 프로퍼티 키로 프로퍼티 값을 저장하면 프로퍼티 어트리뷰티 Set의 값인 setter 함수가 호출되고 그 결과가 프로퍼티 값으로 반환된다.
  • enumrable은 데이터 프로퍼티와 동일하다
  • configurable은 데이터 프로퍼티와 동일하다
const person = {
	firstName: 'Kim',
	lastName: 'yun'
	get fullName() {
		return this.firstName + this.lastName
	}
	set fullName(name){
		[this.firstName,this.lastName] = name.split(',')
	}
}
person.fullName = 'Lee,do'
person.fullName // Leedo
//fullName이 접근자 프로퍼티. 
// 자체적인 값을 가지지 않으며 다만 데이터 프로퍼티 값을 읽거나 저장할 때 관여할 뿐이다.

 

property 정의하기

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

Object.defineProperty 메서드를 통해 정의 가능하다. 인수로는 객체의 참조, 데이터 프로퍼티 키(문자열), 프로퍼티 디스크립터 객체이다. 디스크립터 객체를 기입하지 않으면 undefined나 false가 기본값이다.

const person = {}
Object.defineProperty(person,'firstName',{
	value: 'Kim',
	writable: true,
	enumerable: true,
	configurable: true
}) 
// 위는 데이터 프로퍼티를 추가했고, 
// 접근자 프로퍼티의 프로퍼티 어트리뷰트를 정의하면 접근자 프로퍼티를 추가할 수 있다.

위 메서드는 하나의 프로퍼티에 대해서만 정의하지만 Object.defineProperties는 여러 개의 프로퍼티를 한 번에 정의 할 수 있다

 

객체 변경 방지 메서드들

객체의 변경을 방지하는 다양한 메서드를 제공한다.

1. Object.preventExtensions(객체 확장 금지)

확장 금지 객체인데 추가한다면 에러는 뜨지 않고 무시된다. 단, 엄격모드에서는 에러처리.

프로퍼티의 추가를 금지한다.

확장이 가능한 객체인지 여부는 Object.isExtensible(객체참조명)로 확인 가능하다.

2.Object.seal(객체 밀봉)

프로퍼티의 추가, 삭제, 변경을 금지하고 프로퍼티 어트리뷰트의 재정의를 금지한다. 프로퍼티의 값 갱신, 객체의 읽기, 쓰기만 가능하다. 

여부는 Object.isSealed로 확인 가능하다.

3. Object.freeze(객체 동결)

프로퍼티 추가, 삭제, 변경 금지하고 프로퍼티 어트리뷰트 재정의 금지, 프로퍼티 값 갱신 금지한다. 객체의 읽기만 가능하다. 

여부는 Object.isFrozen으로 가능하다.

 

불변 객체 구현하기

객체 변경 방지는 객체의 직속 프로퍼티만 변경 방지되고 중첩 객체까지는 영향 주지 못한다. 객체의 중첩 객체까지 모두 동결한 읽기 전용 불변 객체를 구현하려면 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 freeze 메서드를 호출해야 한다.

 

'js 이론' 카테고리의 다른 글

js 시간  (0) 2023.08.21
딥다이브 :: 생성자 함수에 의한 객체 생성  (0) 2023.02.02
딥다이브 :: let, const  (0) 2023.01.24
딥다이브 :: 스코프  (0) 2023.01.24
딥다이브 :: 함수  (0) 2023.01.24
Comments