본문 바로가기
FE/JavaScript

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

by thedev 2023. 3. 31.

 

프로퍼티 어트리뷰트

 


 

# 내부 슬롯과 내부 메서드

 

 내부 슬롯과 내부 메서드는 자바스크립트 엔진의 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 것이다. 콘솔 창에서 이중 대괄호로 감싼 이름들이 바로 내부 슬롯과 내부 메서드이다. 내부 슬롯과 내부 메서드는 자바스크립트 엔진의 내부 로직이므로 개발자가 직접 접근하거나 호출할 수 없다. 그러나 일부에 한에서 간접적으로 접근하는 수단이 있긴 하다.

 

객체의 내부 슬롯

 

 예를 들어, 모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖는다. 원칙적으로는 직접 접근할 수 없지만, [[Prototype]]의 경우, __proto__를 통해 간접 접근이 가능하다.

 

const obj = {
  name: "kim",
  age: 20,
  id: 123,
};

console.log(obj);
console.log(obj.__proto__);

 

실행 결과

 

# 프로퍼티 어트리뷰트

 

 자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티 어트리뷰트의 기본값을 생성한다. 프로퍼티 어트리뷰트란 프로퍼티의 상태를 나타내는 내부 슬롯으로, 프로퍼티의 값, 값의 갱신 가능 여부, 열거 가능 여부, 재정의 가능 여부를 의미한다. 각각에 해당하는 내용이 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]라는 내부 슬롯에 저장된다. 위에서 언급했듯 내부 슬롯에 직접 접근할 수는 없지만, 메서드를 사용하여 간접적으로 확인할 수 있다.

 

const obj = {
  name: "kim",
  age: 20,
  id: 123,
};

console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 메서드로 접근

 

실행 결과

 

 프로퍼티를 생성한 것만으로도 프로퍼티의 값(value), 값의 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable)에 대한 내용이 자동으로 정의되어 있는 것을 확인할 수 있다.

 

 

# 데이터 프로퍼티와 접근자 프로퍼티

 

 데이터 프로퍼티는 키와 값으로 구성된 일반적인 프로퍼티이다. 접근자 프로퍼티란, 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티이다. 위에서 살펴본 __proto__가 접근자 프로퍼티에 해당한다.

 

 

# 프로퍼티 정의

 

 프로퍼티 어트리뷰트를 명시적으로 생성하거나, 기존에 있던 프로퍼티 어트리뷰트를 재정의하는 것을 의미한다.

 

const user = {};

Object.defineProperty(user, "user1", {
  value: "kim",
  writable: true,
  enumerable: true,
  configurable: true,
});

Object.defineProperty(user, "user2", {
  value: "lee",
  writable: true,
});

console.log(user); // {user1: 'kim', user2: 'lee'}

 

 프로퍼티 생성 시 프로퍼티 어트리뷰트는 자동 정의되지만, 메서드를 이용하면 명시적으로 지정하거나 재정의할 수 있다.

 

 

# 객체 변경 방지

 

 객체는 변경 가능한 값이다. 프로퍼티가 추가되거나 삭제, 갱신이 가능하고 위의 예시처럼 메서드를 이용하여 프로퍼티 어트리뷰트를 재정의할 수 있다. 만약 객체의 변경을 방지하고 싶다면 객체 변경 방지 메서드를 사용하면 된다.

 

 

1. Object.preventExtensions : 객체 확장 금지, 프로퍼티 추가할 수 없음

 

const user = { name: "kim" };

user.age = 20;
console.log(user); // {name: 'kim', age: 20}

Object.preventExtensions(user);

user.id = 123;
console.log(user); // {name: 'kim', age: 20}

 

 확장을 금지하는 메서드를 사용하면 프로퍼티가 추가되지 않는다.

 

 

2. Object.seal : 객체 밀봉, 프로퍼티 추가, 삭제, 재정의 할 수 없지만 갱신은 가능

 

const user = { name: "kim" };

user.age = 20;
console.log(user); // {name: 'kim', age: 20}

Object.seal(user);

delete user.age;
console.log(user); // {name: 'kim', age: 20}

 

 객체를 밀봉하였기 때문에 프로퍼티 삭제가 되지 않는다.

 

 

3. Object.freeze : 객체 동결, 프로퍼티 추가, 삭제, 재정의, 갱신 모두 불가능 (읽기만 가능)

 

const user = { name: "kim" };

Object.freeze(user);

user.name = "lee";

console.log(user); // {name: 'kim'}

 

 객체를 동결하였기 때문에 오직 읽기만 가능하고, 그 이외의 수정은 불가능하다.

 


 

참고 자료

책 '모던 자바스크립트 Deep Dive' 16장

'FE > JavaScript' 카테고리의 다른 글

[JavaScript] 클로저  (0) 2023.03.27
[JavaScript] this  (0) 2023.03.26
[JavaScript] 프로토타입  (0) 2023.03.17
[JavaScript] 객체지향과 Class 함수  (0) 2023.03.14
[JavaScript] 자주 사용하는 자바스크립트 코드 정리  (1) 2023.03.07