Reflect
Reflect
Reflect 네임스페이스 객체는 가로챌 수 있는(interceptable) JavaScript 객체 내부 메서드를 호출하기 위한 정적 메서드를 담고 있다. 이 메서드들은 proxy handler의 메서드와 동일하다.
본문
개요
대부분의 전역 객체와 달리 Reflect는 생성자(constructor)가 아니다. new 연산자와 함께 사용할 수 없으며 Reflect 객체를 함수로 호출할 수도 없다. Reflect의 모든 속성과 메서드는 정적(static)이다(Math 객체와 마찬가지로, 사실 Math처럼 함수가 아니며 정적 메서드만 제공하는 객체이다).
Reflect 객체는 proxy handler 메서드와 같은 이름을 가진 정적 함수 모음을 제공한다.
Reflect의 주요 용도는 Proxy handler trap에서 기본 전달 동작(default forwarding behavior)을 제공하는 것이다. trap은 객체에 대한 연산을 가로채는 데 사용되며, 객체 내부 메서드에 대한 사용자 정의 구현을 제공한다. Reflect API는 해당 내부 메서드를 호출하는 데 사용된다. 예를 들어 아래 코드는 [[Delete]] 내부 메서드를 가로채는 deleteProperty trap을 가진 프록시 p를 만든다. Reflect.deleteProperty()는 targetObject에서 기본 [[Delete]] 동작을 직접 호출하는 데 사용된다. 이를 delete로 대체할 수도 있지만, Reflect를 사용하면 각 내부 메서드가 어떤 문법에 해당하는지 기억할 필요가 없다.
const p = new Proxy(
{},
{
deleteProperty(targetObject, property) {
// Custom functionality: log the deletion
console.log("Deleting property:", property);
// Execute the default introspection behavior
return Reflect.deleteProperty(targetObject, property);
},
},
);
Reflect 메서드는 또한 내부 메서드가 호출되는 방식을 더 세밀하게 제어할 수 있게 해 준다. 예를 들어 Reflect.construct()는 특정 new.target 값으로 target 함수를 구성하는 유일한 방법이다. new 연산자로 함수를 호출하면 new.target 값은 항상 함수 자신이다. 이는 서브클래싱에서 중요한 영향을 미친다. 또 다른 예로 Reflect.get()은 사용자 정의 this 값으로 getter를 실행할 수 있게 해 주지만, 속성 접근자는 항상 현재 객체를 this 값으로 사용한다.
거의 모든 Reflect 메서드의 동작은 다른 문법이나 메서드로 수행할 수 있다. 일부 메서드는 Object에 같은 이름의 정적 메서드가 있지만 미묘한 차이가 있다. 정확한 차이는 각 Reflect 메서드의 설명을 참고하라.
정적 속성(Static properties)
Reflect[Symbol.toStringTag]—[Symbol.toStringTag]속성의 초기 값은 문자열"Reflect".Object.prototype.toString()에서 사용된다.
정적 메서드(Static methods)
Reflect.apply()—argumentsList파라미터로 지정된 인자로target함수를 호출한다.Function.prototype.apply()도 참고.Reflect.construct()—new연산자를 함수로 표현한 것.new target(...argumentsList)를 호출하는 것과 동등하다. 다른 프로토타입을 지정하는 옵션도 제공한다.Reflect.defineProperty()—Object.defineProperty()와 유사하다. 속성이 성공적으로 정의되었으면true인 불리언을 반환한다.Reflect.deleteProperty()—delete연산자를 함수로 표현한 것.delete target[propertyKey]를 호출하는 것과 동등하다.Reflect.get()— 속성의 값을 반환한다. 객체에서 속성을 가져오는 것(target[propertyKey])을 함수로 표현한 것과 같다.Reflect.getOwnPropertyDescriptor()—Object.getOwnPropertyDescriptor()와 유사하다. 주어진 속성이 객체에 존재하면 그 속성 설명자를, 그렇지 않으면undefined를 반환한다.Reflect.getPrototypeOf()—Object.getPrototypeOf()와 동일하다.Reflect.has()— target이 그 속성을 가지는지(자체 또는 상속) 나타내는 불리언을 반환한다.in연산자를 함수로 표현한 것과 같다.Reflect.isExtensible()—Object.isExtensible()과 동일하다. target이 확장 가능하면true인 불리언을 반환한다.Reflect.ownKeys()— target 객체의 자체(상속되지 않은) 속성 키들의 배열을 반환한다.Reflect.preventExtensions()—Object.preventExtensions()와 유사하다. 업데이트가 성공했으면true인 불리언을 반환한다.Reflect.set()— 속성에 값을 할당하는 함수. 업데이트가 성공했으면true인 불리언을 반환한다.Reflect.setPrototypeOf()— 객체의 프로토타입을 설정하는 함수. 업데이트가 성공했으면true인 불리언을 반환한다.
예제
객체가 특정 속성을 포함하는지 감지하기
const duck = {
name: "Maurice",
color: "white",
greeting() {
console.log(`Quaaaack! My name is ${this.name}`);
},
};
Reflect.has(duck, "color");
// true
Reflect.has(duck, "haircut");
// false
객체의 자체 키 반환하기
Reflect.ownKeys(duck);
// [ "name", "color", "greeting" ]
객체에 새 속성 추가하기
Reflect.set(duck, "eyes", "black");
// returns "true" if successful
// "duck" now contains the property "eyes: 'black'"
명세(Specifications)
- ECMAScript® 2027 Language Specification — sec-reflect-object
브라우저 호환성
baseline 기준 2016년 9월부터 널리 사용 가능하다. 호환성 표는 JavaScript를 활성화해야 볼 수 있다.
참고 자료
Proxy