본문 바로가기
이론/Frontend

JavaScript의 객체 - 2 (Object of JavaScript)

by 유세지 2021. 8. 22.

이전 포스팅에 이어서 객체의 속성에 대해 조금 더 알아보겠습니다.

 

지난 글에서 자바스크립트의 객체가 가진 프로퍼티들이 곧 객체의 특징들이 된다고 언급했었습니다. 이러한 프로퍼티들은 점(.)을 통해 접근하여 읽고 쓸 수 있었습니다. 하지만 모든 프로퍼티가 반드시 접근을 허용하고 있는 것은 아닙니다. 마치 private로 선언된 클래스의 멤버 변수처럼, 외부에서 접근하거나 수정할 수 없는 객체의 프로퍼티들도 존재합니다. 이를 통해 우리는 프로퍼티별로 접근 및 수정에 관한 속성들을 추가로 갖고 있다는 사실을 알 수 있습니다. 

 

그럼 프로퍼티가 가진 속성들을 ES5부터 추가된 프로퍼티 서술자를 이용해 확인해보겠습니다.

 

 

프로퍼티 서술자

let obj = { val:1 };

Object.getOwnPropertyDescriptor(obj, "val");

 

 

Object.getOwnPropertyDescriptor() 를 사용하면 객체가 가진 프로퍼티의 속성을 확인할 수 있습니다. 우리가 지정해주었던 value값 1과 Object로부터 연결된 [[Prototype]]: Object 를 제외하고 세 가지 속성을 더 확인할 수 있습니다.

 

configurable은 설정 가능 여부를 나타냅니다. true일 경우 프로퍼티의 서술자를 변경하거나, delete 연산자를 이용한 삭제가 가능합니다. 위와 같이 값을 할당하는 방법으로 생성한 프로퍼티의 경우 기본적으로 true인 상태입니다.

 

enumerable은 열거 가능 여부를 나타냅니다. true일 경우 for in 루프와 같은 경우에서 프로퍼티를 노출시킵니다. 마찬가지로 값을 할당하여 생성하면 기본적으로 true입니다.

 

writable은 쓰기 가능 여부를 나타냅니다. true일 경우 값을 변경하기가 가능해지고, 역시 기본적으로 true입니다.

 

위 속성들이 false로 설정되어있는데 값을 수정하거나 서술자를 변경하는 등 금지된 작업을 하게되면 TypeError를 출력하게 됩니다.

 

TypeError

 

추가적으로, 값을 할당해서 프로퍼티를 만드는 방식이 아닌 Object.defineProperty()를 이용해 프로퍼티를 생성하면 기본적으로 false가 됩니다.

 

기본값은 false

 

 

불변성

객체에는 불변성을 보장할 여러 방법이 존재합니다. 가까운 예시로 위에서 언급한 프로퍼티 서술자의 writable, configurable 속성을 false로 설정하면 값을 수정할 수도, 삭제할 수도 없는 일종의 상수처럼 사용할 수 있습니다.

Object.defineProperty(obj, "val", {
	writable: false,
    configurable: false
});

 

객체가 지금 가지고 있는 프로퍼티는 유지하고, 더 이상의 프로퍼티 추가없이 사용하고 싶을땐 Object.preventExtensions()를 사용합니다.

Object.preventExtensions(obj);

 

객체에 configurable: false프로퍼티 추가 제한을 한 번에 걸어 봉인하고 싶을땐 Object.seal() 을 이용합니다. 프로퍼티의 추가는 불가능하지만, 이미 존재하는 프로퍼티의 값을 변경하는것은 가능합니다.

Object.seal(obj);

 

객체에 configurable: falsewritable: false, 프로퍼티 추가 제한을 한 번에 걸어 객체를 동결시킬때는 Object.freeze() 를 이용합니다.

Object.freeze(obj);

 

상황에 맞는 메소드를 사용하면 위처럼 객체의 불변성을 쉽게 조작할 수 있습니다.

 

 

순회

위에서 프로퍼티 서술자를 설명하며 for in 루프enumerable: true 인 프로퍼티를 순회한다고 이야기 하였습니다.

let obj = {a: 1, b: 2, c: 3};

for (const prop in obj) {
  console.log(`${prop} = ${obj[prop]}`);
}

 

이렇게 프로퍼티를 순회하여, 프로퍼티 이름을 인덱스로 삼아 `${obj[prop]}` 와 같은 형식으로 출력할 수 있습니다. 

이 방법은 프로퍼티의 값이 아닌 프로퍼티 자체를 순회하여 간접적인 참조를 통해 값을 출력하였습니다. ES6에 추가된 for of 루프는 값을 직접 순회할 수 있게 도와줍니다.

 

let obj = [1, 2, 3];

for (const prop of obj) {
  console.log(`${prop}`);
}

 

다만 for of 루프는 순회할 원소의 이터레이터 객체가 있어야 정상적으로 작동하게 됩니다. 이터러블/이터레이터 관련해서는 따로 정리하도록 하겠습니다. 할 이야기도 많으니까요. :)

 

 

 

 

두 포스팅에 걸쳐 객체에 대해 알아보았습니다. 다음은 객체지향의 꽃, 클래스에 대한 이야기를 해보겠습니다.

부족한 글 읽으시느라 고생 많으셨습니다. 감사합니다.

반응형

댓글