constructor function with getter / setter

Yoseob Shin·2022년 4월 19일
0

javascript

목록 보기
14/24
post-thumbnail
post-custom-banner

오늘 갑자기 궁금하게 된 점이 있었는데,

class 로 객체 인스턴스를 생성할때는 getter와 setter를 만들기가 쉬웠지만
생산형 함수에는 어떻게 하는지 몰랐다.

MDN을 참고해보니 이런 방법이 있었다.

Defining a getter on existing objects using Object.defineProperty()

To append a getter to an existing object later at any time, use Object.defineProperty().

const o = {a: 0};

Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });

console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)

이 방법을 참고하면 이렇게 할수 있다.

//예시:
const Test = function () {
  this.__a = 3;
  
  Object.defineProperty(this, 'a', {
    get: function() {
      return this.__a 
    },
    set: function(n) {
      console.log(this)
      return this.__a = n;
    }
  })
}

const test1 = new Test();

console.log(test1.a) // 3 
console.log(test1.a = 5) //5
console.log(Object.getOwnPropertyDescriptor(test1, 'a')); 
/*{
  get: ƒ get(),
  set: ƒ set(),
  enumerable: false,
  configurable: false
} */
console.log(Object.getOwnPropertyDescriptor(
    Object.getPrototypeOf(test1), 'a'
  )) // undefined 

혹은 프로토 타입 사용:

function Something(defaultFoo) {
    this._foo = defaultFoo;
}

Object.defineProperty(Something.prototype, 'foo', {
    get: function() {
        return this._foo;
    },
    set: function(value) {
        this._foo = value;
    }
});

var something = new Something("bar");
console.log(something.foo);
something.foo = 'baz';
console.log(something.foo);

Object.defineProperty(객체인수, 속성이름, descriptors)를 생산 함수 안에 사용해 생산형 함수에도 각 인스턴스 객체들에게 getter 나 setter 접근형 매소드를 형성 할수 있다.


다만 이러한 점에서 한가지 약간의 차이점이 있는데 Object.defineProperty는 인스턴스 객체의 속성값을 정의 하고 일반 getter /setter 는 객체의 Prototype에 속성값을 정의 한다.

class Example {
  get hello() {
    return 'world';
  }
}

const obj = new Example();
console.log(Object.getOwnPropertyDescriptor(obj, 'hello')); // undefined
console.log(
  Object.getOwnPropertyDescriptor(
    Object.getPrototypeOf(obj), 'hello'
  )
); 
// {
  get: ƒ get hello(),
  set: undefined,
  enumerable: false,
  configurable: true
}

const obj2 = new Example();
Object.defineProperty(obj2, 'hello2', {
 value: 'world2',
  writable: true
}) 

console.log(Object.getOwnPropertyDescriptor(obj2, 'hello2')); 
// {
  value: 'world2',
  writable: true,
  enumerable: false,
  configurable: false
}

console.log(
  Object.getOwnPropertyDescriptor(
    Object.getPrototypeOf(obj2), 'hello2'
  )
); // undefined
profile
coder for web development + noodler at programming synthesizers for sound design as hobbyist.
post-custom-banner

0개의 댓글