LHJ

I'm a FE developer.

17-3. Object 오브젝트(ES5 기준) / 프로퍼티 디스크립터, value/writable/enumerable/configurable 속성

06 Dec 2020 » js_beginner

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북