오늘 갑자기 궁금하게 된 점이 있었는데,
class 로 객체 인스턴스를 생성할때는 getter와 setter를 만들기가 쉬웠지만
생산형 함수에는 어떻게 하는지 몰랐다.
MDN을 참고해보니 이런 방법이 있었다.
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