JavaScript의 Reflect는 intercept 가능한 JavaScript 작업에 대한 메서드를 제공하는 내장 객체입니다. Math 객체와 유사하게 Reflect는 함수 객체가 아니며 생성자로 사용할 수 없습니다. 즉, new 연산자를 통해 인스턴스를 생성할 수 없으며 모든 메서드는 정적(static)으로 호출됩니다.
Reflect.apply()
대상 함수를 지정된 인수와 함께 호출합니다. 이는 Function.prototype.apply()와 유사한 역할을 수행합니다.
// Reflect.apply(target, thisArgument, argumentsList)
function greet(user) {
return `안녕하세요, ${user}님!`;
}
// 기본 사용법
const message = Reflect.apply(greet, null, ['홍길동']);
console.log(message); // "안녕하세요, 홍길동님!"
// Math.max 활용 예시
const numbers = [10, 20, 30, 40];
const maxVal = Reflect.apply(Math.max, undefined, numbers);
console.log(maxVal); // 40
// String.prototype.includes 호출
const str = "Hello World";
const hasWorld = Reflect.apply(String.prototype.includes, str, ["World"]);
console.log(hasWorld); // true
Reflect.construct()
new 연산자와 동일한 기능을 수행합니다. 가변 인자를 사용하여 생성자를 호출할 때 유용합니다.
function Person(name, age) {
this.name = name;
this.age = age;
}
// new Person('Kim', 25)와 동일
const member = Reflect.construct(Person, ['Kim', 25]);
console.log(member.name); // "Kim"
// Array 생성 예시
const items = Reflect.construct(Array, [5]); // 길이가 5인 배열 생성
console.log(items.length); // 5
Reflect.defineProperty()
객체에 새로운 속성을 정의하거나 기존 속성을 수정합니다. Object.defineProperty()와 비슷하지만, 성공 여부를 Boolean으로 반환한다는 차이점이 있습니다.
const config = {};
if (Reflect.defineProperty(config, 'version', { value: '1.0.0', writable: false })) {
console.log('속성 정의 성공');
} else {
console.log('속성 정의 실패');
}
Reflect.deleteProperty()
객체의 속성을 삭제합니다. delete 연산자와 기능적으로 동일하며, 작업의 성공 여부를 논리값으로 반환합니다.
const session = { id: 1, token: 'abc' };
const success = Reflect.deleteProperty(session, 'token');
console.log(success); // true
console.log(session); // { id: 1 }
Reflect.get() 및 Reflect.set()
속성 값을 읽거나 설정합니다. 객체의 프로퍼티 접근자(obj[key])와 할당문 역할을 수행합니다.
const state = { count: 0 };
// 값 설정
Reflect.set(state, 'count', 10);
// 값 조회
const currentCount = Reflect.get(state, 'count');
console.log(currentCount); // 10
Reflect.has()
객체에 특정 속성이 존재하는지 확인합니다. in 연산자와 동일하게 작동합니다.
const meta = { title: 'JS Guide' };
console.log(Reflect.has(meta, 'title')); // true
console.log(Reflect.has(meta, 'author')); // false
Reflect.getPrototypeOf() 및 Reflect.setPrototypeOf()
객체의 프로토타입을 조회하거나 변경합니다. Object의 관련 메서드와 유사하지만 일관된 반환 형식을 제공합니다.
const proto = { base: true };
const instance = Object.create(proto);
console.log(Reflect.getPrototypeOf(instance) === proto); // true
const newProto = { base: false };
Reflect.setPrototypeOf(instance, newProto);
console.log(Reflect.getPrototypeOf(instance).base); // false
Reflect.ownKeys()
객체 자체의 모든 속성 키(문자열 및 Symbol 모두 포함)를 배열로 반환합니다. Object.getOwnPropertyNames()와 Object.getOwnPropertySymbols()를 합친 것과 같습니다.
const uniqueId = Symbol('id');
const metadata = {
[uniqueId]: 101,
tag: 'alpha'
};
Reflect.defineProperty(metadata, 'hidden', {
value: 'secret',
enumerable: false
});
// 모든 종류의 키를 추출
console.log(Reflect.ownKeys(metadata));
// Output: ["tag", "hidden", Symbol(id)]
Reflect.isExtensible() 및 Reflect.preventExtensions()
객체의 확장 가능 여부를 확인하거나 확장을 금지합니다.
const schema = { type: 'object' };
console.log(Reflect.isExtensible(schema)); // true
Reflect.preventExtensions(schema);
console.log(Reflect.isExtensible(schema)); // false