본문으로 바로가기

Object.defineProperty

category JavaScript 2021. 9. 6. 02:45

Object.defineProperty(객체, 프로퍼티, 설명) 정적 메서드는 객체에 직접 새로운 속성을 정의하거나 이미 존재하는 속성을 수정한 후, 그 객체를 반환한다

MDN에 나와있는 정의.

말이 어려운데 쉽게 설명하자면 객체 내부에 있는 프로퍼티설명을 따라서 해당하는 속성을 정의하거나 수정하고 다시 객체를 반환하는 Object의 정적 메서드이다

const obj = {};

Object.defineProperty(obj, 'value', {
    value:1000,
}); // 이 때 반환값은 obj 객체

console.log(obj); // {value: 1000}

defineProperty 에서 설명은 보다시피 객체로 서술되며 데이터 서술자와, 접근자 서술자 두 가지 종류로 나뉘게 된다

좀 더 자세한 설명들은 https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

에 나와있고 내가 알아볼 것은 접근자 서술자이다

접근자 서술자는 classsettergetter를 일반 객체에서도 적용시켜주는 역할을 한다고 보면 된다

먼저 익숙한 클래스의 settergetter를 살펴보자

class Obj {
        constructor(a) {
            this.a = a;
        }

        get getA(){
            console.log('get');
            return this.a;
        }

        set setA(nextValue){
            console.log('set');
            this.a = nextValue;
        }
    }
const obj = new Obj('test');
obj.getA; // obj.a => 'test'
// console log print 'get'
obj.setA = 'asdf'; // obj.a => 'asdf'
// console log print 'set'

클래스에서는 obj 내부의 값이 바뀔 때 무언가 로직을 추가해 줄 수 있다

defineProperty 의 접근 서술자도 마찬가지다 클래스가 아닌 일반 객체 내부의 값을 수정, 접근할 때

그 행동을 가로채서 내가 원하는 다른 로직을 끼워넣고 반환시킬 수 있게 해주는 getset을 설정할 수 있다

const obj = {};

Object.defineProperty(obj, 'a', {
    get(){
        console.log('get');
        return this._a;
    },
    set(nextValue){
        console.log('set');
        this._a = nextValue;
      }
});

obj.a // obj.a => undefined
// console log print 'get'

obj.a = 'test' // obj.a => test
// console log print 'set'

obj 객체의 a라는 프로퍼티에 대해서 getset을 설정하는 코드이다

여기서 this._a 에 접근하는 코드에서 나는 헷갈림이 있었다 이해를 돕기위한 간단 설명을 해보자면

(thisobj를 가르킨다)

this.a에 바로 접근하게 코드를 수정했다고 생각하고 코드의 실행 과정을 살펴보자

  1. obj.a 라는 코드로 a에 접근하게 되어 get()을 호출한다
  2. console.log('get')을 호출한다
  3. this.aobj.a 이므로 다시 get() 을 호출한다
  4. 1~3 무한 반복

그래서 obj.a에 바로 접근하면 해당 프로퍼티에 직접 접근하는 것이 아닌 내부에만 존재하는 것으로 취급하는 _a로 연결시키고 접근하고 수정하는 것이다

'JavaScript' 카테고리의 다른 글

클래스, 믹스인 (Mixin)  (0) 2021.07.13
defer, async 스크립트  (0) 2021.07.12
주요 노드 프로퍼티  (0) 2021.07.09
DOM 수정  (0) 2021.07.08
modal에 keydown 이벤트 추가하기 (tabindex)  (0) 2021.06.02