17-3. Object 오브젝트(ES5 기준) / 프로퍼티 디스크립터, value/writable/enumerable/configurable 속성
프로퍼티 디스크립터
6개의 디스크립터가 있습니다.
디폴트 값은 ‘부정’을 의미하는 값이 대부분입니다.
프로퍼티 디스크립터(Descriptor)
- 프로퍼티의 속성 이름과 속성 값을 정의
디스크립터 타입 분류 (위의 표 제일 왼족)
- 데이터 프로퍼티 디스크립터
- 엑세스(Access) 프로퍼티 디스크립터
- 공용 프로퍼티 디스크립터
디스크립터 타입에 속한 속성만 같이 사용할 수 있음
- value, writable
- get, set
- enumerable, configurable (공용)
value와 get을 같이 사용할 수 없다.
마찬가지로 writable과 set을 같이 사용할 수 없다.
공용은 같이 작성할 수 있다.
get과 enumerable은 같이 작성할 수 있다. 데이터와 엑세스는 같이 작성을 못하는 것이 특징이다.
디스크립터 타입 인식 기준
타입 | 속성 이름 |
---|---|
데이터 | value writable |
엑세스 | get set |
공용 | enumerable configurable |
- 먼저 value 또는 writable 작성 체크
작성되어 있으면
- 데이터 프로퍼티 디스크립터 타입으로 인식
작성되어 있지 않으면
- 엑세스 프로퍼티 디스크립터 타입으로 인식
- 데이터와 엑세스 프로퍼티 디스크립터를 함께 작성할 수 없으므로 구분 가능
value 속성
프로퍼티 값을
- {value: “JS북”} 형태로 작성
for~in에서 “JS북”이 프로퍼티 값이 됨
var obj = {}; Object.defineProperty(obj, "book", { value: "JS북", enumerable: true }) for (var name in obj) { console.log(name); console.log(obj[name]); } // book // JS북
value 속성을 get/set 속성과 같이 작성 불가
var obj = {}; Object.defineProperty(obj, "book", { value: "JS북", // get: function () {} })
writable 속성
- 프로퍼티 값 변경 가능, 불가
writable: true
프로퍼티 변경 가능
var obj = {}; Object.defineProperty(obj, "book", { value: "JS책", // 변경 가능 writable: true }) obj.book = "변경 가능"; console.log(obj.book); // 변경 가능
writable: false
- 디폴트 값: false
프로퍼티 변경 불가
에러가 발생하지 않지만, 값이 변경되지 않음var obj = {}; Object.defineProperty(obj, "book", { value: "JS책", // 변경 불가 writable: false }) // 아래 코드에서 에러가 안납니다. // 에러가 안나는 점이 오히려 조금 아쉽기도 합니다. 체크하기 어려울 수도.. // 그래도 나름 이해가 되는 부분입니다. // 코드가 중간에 멈추는 것을 방지하기 위함이겠지만, 살짝 마음에 걸리는 부분입니다. obj.book = "변경 불가"; console.log(obj.book); // JS책
enumerable 속성
for~in
으로 열거 가능 여부enumerable: true
프로퍼티 열거 가능
var obj = {}; Object.defineProperty(obj, "book", { value: "JS북", // 열거 가능 enumerable: true }) for (var name in obj) { console.log(name, ":" + obj[name]); } // book:JS북
enumerable: false
- 디폴트 값: false
프로퍼티 열거 불가
var obj = {}; Object.defineProperty(obj, "book", { value: "JS북", // 열거 불가 enumerable: false }) for (var name in obj) { console.log(name, ":" + obj[name]); }
이 또한 데이터 보호 차원이 될 수 있습니다.
물론 소스가 오픈되어있고 debugger로 보면 볼 수 있지만 또 그것은 다른관점이죠.
configurable 속성
- 프로퍼티 삭제 가능, 불가
configurable: true
- 프로퍼티 삭제 가능
value 이외 속성 변경 가능
var obj = {}; Object.defineProperty(obj, "book", { value: "JS북", // 삭제 가능 configurable: true }) delete obj.book; console.log(obj.book); // undefined
configurable: false
- 디폴트 값 : false
- 프로퍼티 삭제 불가
value 이외 속성 변경 불가
var obj = {}; Object.defineProperty(obj, "book", { value: "JS북", // 삭제 불가 configurable: false }) // 마찬가지로 삭제 불가인데 다음과 같이 삭제해도 에러가 안납니다. // 물론 삭제도 안됩니다. // 코드가 중간에 멈추는 것을 방지하기 위함이겠지만, 살짝 마음에 걸리는 부분입니다. delete obj.book; console.log(obj.book); // JS북