새소식

FE/JavaScript

[Javascript] 프로퍼티 어트리뷰트

  • -

🍉 1. 내부 슬롯과 내부 매서드

  • 프로퍼티 어트리뷰트를 이해하기 위한 개념
  • 내부 슬롯내부 메서드는 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티(pseudo property)와 의사 메서드(pseudo method)다.
  • 자바스크립트 엔진에서 실제로 동작하지만, 외부로 공개된 객체의 프로퍼티는 아니다. -> 직접 접근할 수 없음

 

🍉 2. 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체

자바스크립트 엔진은 프로퍼티를 생성할 때, 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.

 

프로퍼티 상태

: 프로퍼티의 값(value), 값의 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable) 

 

프로퍼티 어트리뷰트

: 내부 상태 값인 내부 슬롯 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]

-> 프로퍼티 어트리뷰트에 직접 접근 X

-> Object.getOwnPropertyDescriptor 메서드 사용하여 간접적 확인 O

 

const person = { name: 'Lee' }; // 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다. console.log(Object.getOwnPropertyDescriptor(person, 'name')); // {value: "Lee", writable: true, enumerable: true, configurable: true} //Object.getOwnPropertyDescriptor 메서드를 호출할 때 //첫 번째 매개변수=> 객체의 참조 전달 //두 번째 매개변수=> 프로퍼티 키를 문자열로 전달 //프로퍼티 디스트립터 객체(프로퍼티 어트리뷰트 정보 제공) 반환

 

 

🍉 3. 데이터 프로퍼티와 접근자 프로퍼티

프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있다.

 

1) 데이터 프로퍼티

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

 

다음과 같은 프로퍼티 어트리뷰트를 갖는다. 이 프로퍼티 어트리뷰트는 자바스크립트 엔진이 프로퍼티를 생성할 때 기본값으로 자동 정의된다.

 

 

프로퍼티 어트리뷰트 프로퍼티 디스크립터 객체의 프로퍼티 설명
[[Value]] value 1. 프로퍼티 키를 통해 값에 접근하면 반환되는 값.
2. 프로퍼티 키를 통해 프로퍼티 값을 변경하면 [[Value]]에 값을 재할당. / 이때 프로퍼티 없으면 동적 생성하여 저장
[[Writable]] writable 1. 프로퍼티 값의 변경 가능 여부 - 불리언 값을 가짐
2. [[Writable]]의 값이 false인 경우, 읽기 전용 프로퍼티가 됨
[[Enumerable]] enumerable 1. 프로퍼티의 열거 가능 여부 - 불리언 값
2. [[Enumerable]]의 값이 false 인 경우, 
for...in문이나 Object.keys 메서드 등으로 열거 불가
[[Configurable]] configurable 1. 프로퍼티 재정의 가능 여부 - 불리언 값
2. [[Configurable]]의 값이 false 인 경우, 삭제, 값의 변경 금지
단, [[Writable]]이 true인 경우, [[Valule]]의 변경과 [[Writable]]을 false로 변경 허용

 

const person = { name: 'Lee' }; person.age = 20; //프로퍼티 동적 생성 console.log(Object.getOwnPropertyDescriptor(person)); /* {value: "Lee", writable: true, enumerable: true, configurable: true} {value: "20", writable: true, enumerable: true, configurable: true} */

 

 

2) 접근 프로퍼티

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

 

다음과 같은 프로퍼티 어트리뷰트를 갖는다.

 

프로퍼티 어트리뷰트 프로퍼티 디스크립터 객체의 프로퍼티 설명
[[Get]] get 1. 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수
2. [[Get]]의 값, 즉 getter 함수 호출 -> 프로퍼티 값으로 변환
[[Set]] set 1. 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수
2. [[Set]]의 값, 즉 setter 함수 호출 -> 프로퍼티 값으로 저장
[[Enumerable]] enumerable 데이터 프로퍼티의 [[Enumerable]]과 같다
[[Configurable]] configurable 데이터 프로퍼티의 [[Configurable]]과 같다

 

접근자 함수는 getter/setter 함수라고도 부른다.

 

🍉 4. 프로퍼티 정의

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

 

Object.defineProperty 메서를 사용하면 프로퍼티의 어트리뷰트를 정의할 수 있다.

인수로는 객체의 참조, 데이터 프로퍼티의 키(문자열), 프로퍼티 디스크립터 객체를 전달한다.

 

const person = {}; // 데이터 프로퍼티 정의 Object.defineProperty(person, 'firstName', { value: 'Ungmo', writable: true, enumerable: true, configurable: true }); Object.defineProperty(person, 'lastname', { value:'Lee' }); let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName'); console.log('firstName', descriptor); // firstName {value: "Ungmo", writable: true, enumerable: true, configurable: true}

 

  • Object.defineProperty 메서드는 한번에 하나의 프로퍼티만 정의할 수 있다.
  • Object.defineProperties 메서드를 사용하면 여러 개의 프로퍼티를 한 번에 정의할 수 있다.

 

🍉 5. 객체 변경 방지

객체는 변경 가능한 값이므로 재할당 없이 직접 변경할 수 있다.

ex) 프로퍼트 추가,삭제,갱신

ex) 프로퍼티 어트리뷰트 재정의 ( Object.defineProperty, Object.defineProperties 사용)

 

따라서 자바스크립트는 객체의 변경을 방지하는 다양한 메서드를 제공한다.

 

간단히 표로 정리하면 다음과 같다.

 

구분 메서드 프로퍼티
추가
프로퍼티 삭제 프로퍼티 값
읽기
프로퍼티 값
쓰기
프로퍼티 어트리뷰트 재정의
객체 확장 금지 Object.preventExtensions X O O O O
객체 밀봉 Object.seal X X O O X
객체 동결 Object.freeze X X O X X

 

위 내용을 자세히 살펴보자.

 

 

 

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

Object.preventExtensions 메소드는 객체에 새로운 프로퍼티를 추가할 수 없도록 설정한다. 하지만, 이미 존재하는 프로퍼티의 값은 변경할 수 있다. 이 때, [[Extensible]] 프로퍼티가 false로 변경된다.

 

let person = { name: 'Sumin', age: 20 }; Object.preventExtensions(person); person.gender = 'Male'; // 프로퍼티 추가 무시됨 (strict mode에서는 TypeError 발생) console.log(person); // { name: 'Sumin', age: 20 } console.log(Object.isExtensible(person)); // false

 

 

2. 객체 밀봉(Object.seal)

 

Object.seal 메소드는 다음을 금지하며, 이를 객체 밀봉이라 한다.

  • 프로퍼티 추가 금지
  • 프로퍼티 삭제 금지
  • 프로퍼티 어트리뷰트 재정의 금지

밀봉된 객체는 읽기와 쓰기만 가능하다.

 

let person = { name: 'Sumin', age: 20 }; Object.seal(person); delete person.age; // 프로퍼티 삭제 무시됨 (strict mode에서는 TypeError 발생) person.gender = 'Male'; // 프로퍼티 추가 무시됨 (strict mode에서는 TypeError 발생) person.name = 'Mike'; // 프로퍼티 값 갱신은 가능 Object.defineProperty(person,'name',{configurableL:true}); // 프로퍼티 어어트리뷰트 재정의 금지 console.log(person); // { name: 'Mike', age: 30 } console.log(Object.isSealed(person)); // true

 

 

3. 객체 동결(Object.freeze)

Object.freeze 메소드는 다음을 금지하며, 이를 객체 동결이라 한다.

  • 프로퍼티 추가 금지
  • 프로퍼티 삭제 금지
  • 프로퍼티 어트리뷰트 재정의 금지
  • 프로퍼티 값 갱신 금지

동결된 객체는 읽기만 가능하다.

 

let person = { name: 'Sumin', age: 20 }; Object.freeze(person); //객체 동결 delete person.age; // 무시됨 (strict mode에서는 TypeError 발생) person.gender = 'Male'; // 무시됨 (strict mode에서는 TypeError 발생) person.name = 'Mike'; // 무시됨 (strict mode에서는 TypeError 발생) console.log(person); // { name: 'Sumin', age: 20 } console.log(Object.isFrozen(person)); // true

 

4. 불변객체(Immutable Object)

 

불변객체(Immutable Object)는 객체 생성 후 객체의 상태를 변경할 수 없는 객체로 이러한 객체는 생성 이후에는 추가, 삭제, 수정이 불가능하며, 객체 내부의 프로퍼티들도 불변한다. 대신, 객체를 변경하는 대신에 새로운 객체를 생성하거나 복사해서 원하는 상태를 만들 수 있다.

 

 


Reference

 

https://ganxdev.tistory.com/83

 

 

https://www.inflearn.com/course/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C

 

[지금 무료] 모던 자바스크립트 딥다이브 스터디 강의 | 정재남 - 인프런

정재남 | 《모던 자바스크립트 딥다이브》 책 내용을 그대로 따라가는 스터디 영상입니다. 함께 공부하면 훨씬 쉬워질 거에요!, 혼자가 외롭다면 시간차 스터디는 어때요?함께하는 모던 자바스

www.inflearn.com

 

https://msj725.tistory.com/159

 

[자바스크립트] 프로퍼티 어트리뷰트(Property Attribute)

본 내용은 이웅모 님의 모던 "자바스크립트 DeepDive" 책을 보고 정리한 내용입니다. 저작권 보호를 위해 책의 내용은 요약되었습니다. 내부슬롯과 내부 메서드 - 내부슬롯과 내부 메서드는 JavaScrip

msj725.tistory.com

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.