JavaScript에서 객체의 속성(property)을 정의하는 방법은 크게 두 가지가 있습니다. 하나는 점 표기법(Dot notation)과 대괄호 표기법(Bracket notation)을 사용하는 방식이고, 다른 하나는 Object.defineProperty() 메서드를 활용하는 방식입니다.
Object.defineProperty()는 일반적으로 세 가지 매개변수를 받습니다. 바로 객체 이름, 속성 이름, 그리고 속성 설명자(property descriptor)입니다.
문법
Object.defineProperty(객체이름, 속성이름, 속성설명자)
그럼 이 메서드를 사용해 실제로 속성을 정의해 보겠습니다.
예제 1: enumerable을 지정하지 않은 경우
다음 예제에서는 처음에 객체에 'one'이라는 속성 하나만 존재합니다. 이후 Object.defineProperty()를 통해 'two'라는 새로운 속성을 추가했습니다. 하지만 모든 속성을 출력해 보면 아래 결과처럼 처음부터 있던 첫 번째 속성만 표시되고, 나중에 추가한 속성은 화면에 나타나지 않습니다.
<html>
<body>
<script>
var object = {one: 1};
Object.defineProperty(
object,
'two', {
value: 2
}
);
document.write(JSON.stringify(object));
</script>
</body>
</html>출력 결과
{"one":1}원인: enumerable 속성
이러한 현상이 발생하는 이유는 바로 'enumerable'(열거 가능) 속성 때문입니다. 객체에 정의된 속성이 열거되려면 enumerable 값이 반드시 true여야 합니다. 그런데 Object.defineProperty()를 사용할 때 enumerable을 별도로 선언하지 않으면 기본값이 false로 설정됩니다. 따라서 해당 속성은 존재하더라도 JSON.stringify()나 for...in 루프 같은 열거 작업에서 제외되어 출력되지 않는 것입니다.
이 문제를 해결하려면 속성 설명자 안에 enumerable을 명시적으로 선언하고 값을 true로 지정해 주어야 합니다.
예제 2: enumerable을 true로 설정한 경우
다음 예제에서는 enumerable을 선언하고 true로 할당했습니다. 그 결과 모든 속성이 정상적으로 출력되는 것을 확인할 수 있습니다.
<html>
<body>
<script>
var object = {one: 1};
Object.defineProperty(
object,
'two', {
value: 2,
enumerable: true
}
);
document.write(JSON.stringify(object));
</script>
</body>
</html>출력 결과
{"one":1,"two":2}정리
Object.defineProperty()로 속성을 추가할 때는 enumerable뿐만 아니라 writable(쓰기 가능), configurable(구성 가능) 등의 속성 설명자도 함께 고려해야 합니다. 이들은 각각 기본값이 false이므로, 의도한 동작을 얻으려면 필요한 옵션을 명확하게 명시하는 것이 좋습니다. 특히 외부 라이브러리 개발이나 내부 상태를 숨겨야 하는 경우에는 enumerable: false가 오히려 유용하게 활용될 수 있습니다.