javascript中的反射指的是程序在运行阶段可以动态获取自身信息、修改自身结构和行为的能力,不需要在编译阶段就确定所有操作逻辑。Reflect是javascript内置的全局对象,它提供了一系列静态方法,这些方法对应了javascript中可被拦截的内部操作,是实现反射能力的核心工具,同时也和Proxy代理对象的陷阱方法形成一一对应的关系。

Reflect对象的核心特性
Reflect并不是构造函数,不能使用new操作符去实例化,也不能调用它作为函数执行,所有方法都是静态方法,直接通过Reflect.methodName的形式调用即可。它的方法设计遵循统一的规则,大部分方法的返回值都是操作结果,成功返回true,失败返回false,而不是像传统操作那样抛出错误,这让错误处理更加方便。
和传统的对象操作方法相比,Reflect的方法更加规范,比如传统的delete操作符删除对象属性时,如果属性是不可配置的就会抛出错误,而Reflect.deleteProperty会返回false表示操作失败。下面是两者的对比示例:
const obj = {};
Object.defineProperty(obj, 'name', {
value: 'test',
configurable: false
});
// 传统delete操作,会抛出错误
try {
delete obj.name;
} catch (e) {
console.log('delete操作失败:', e.message);
}
// Reflect.deleteProperty操作,返回false
const result = Reflect.deleteProperty(obj, 'name');
console.log('Reflect操作结果:', result); // 输出 false
Reflect对象的全部方法说明
Reflect对象一共提供了13个静态方法,覆盖了javascript中大部分可拦截的内部操作,下面逐个介绍每个方法的作用和使用场景。
1. Reflect.get(target, propertyKey[, receiver])
该方法用于读取目标对象的指定属性,等价于target[propertyKey],但是支持receiver参数的传递,当属性是getter时,getter中的this会指向receiver。
const target = {
name: '张三',
get age() {
return this._age || 0;
}
};
const receiver = { _age: 20 };
const name = Reflect.get(target, 'name');
const age = Reflect.get(target, 'age', receiver);
console.log(name); // 输出 张三
console.log(age); // 输出 20
2. Reflect.set(target, propertyKey, value[, receiver])
该方法用于设置目标对象的指定属性值,等价于target[propertyKey] = value,同样支持receiver参数,当属性是setter时,setter中的this会指向receiver,操作成功返回true,失败返回false。
const target = {
set name(val) {
this._name = val;
},
get name() {
return this._name;
}
};
const receiver = {};
const setResult = Reflect.set(target, 'name', '李四', receiver);
console.log(setResult); // 输出 true
console.log(receiver._name); // 输出 李四
3. Reflect.has(target, propertyKey)
该方法用于判断目标对象是否存在指定属性,等价于propertyKey in target,返回布尔值。
const obj = { a: 1, b: 2 };
console.log(Reflect.has(obj, 'a')); // 输出 true
console.log(Reflect.has(obj, 'c')); // 输出 false
4. Reflect.deleteProperty(target, propertyKey)
该方法用于删除目标对象的指定属性,等价于delete target[propertyKey],操作成功返回true,失败返回false,不会抛出错误。
const obj = { x: 10, y: 20 };
const delResult = Reflect.deleteProperty(obj, 'x');
console.log(delResult); // 输出 true
console.log(obj); // 输出 { y: 20 }
5. Reflect.construct(target, argumentsList[, newTarget])
该方法用于调用构造函数创建实例,等价于new target(...argumentsList),newTarget参数可以指定实例的原型构造函数,操作结果返回新创建的实例。
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
console.log(`你好,我是${this.name}`);
};
const instance = Reflect.construct(Person, ['王五']);
instance.sayHi(); // 输出 你好,我是王五
6. Reflect.getPrototypeOf(target)
该方法用于获取目标对象的原型,等价于Object.getPrototypeOf(target),如果目标不是对象会抛出错误。
const obj = {};
const proto = Reflect.getPrototypeOf(obj);
console.log(proto === Object.prototype); // 输出 true
7. Reflect.setPrototypeOf(target, prototype)
该方法用于设置目标对象的原型,等价于Object.setPrototypeOf(target, prototype),操作成功返回true,失败返回false。
const obj = {};
const newProto = { type: 'custom' };
const setProtoResult = Reflect.setPrototypeOf(obj, newProto);
console.log(setProtoResult); // 输出 true
console.log(obj.type); // 输出 custom
8. Reflect.apply(target, thisArgument, argumentsList)
该方法用于调用目标函数,指定函数执行时的this指向和参数列表,等价于Function.prototype.apply.call(target, thisArgument, argumentsList),可以避免目标函数被修改apply方法带来的问题。
function sum(a, b) {
return a + b;
}
const applyResult = Reflect.apply(sum, null, [3, 5]);
console.log(applyResult); // 输出 8
9. Reflect.defineProperty(target, propertyKey, attributes)
该方法用于在目标对象上定义属性,等价于Object.defineProperty,但是操作成功返回true,失败返回false,不会抛出错误。
const obj = {};
const defineResult = Reflect.defineProperty(obj, 'id', {
value: 1001,
writable: false
});
console.log(defineResult); // 输出 true
console.log(obj.id); // 输出 1001
10. Reflect.getOwnPropertyDescriptor(target, propertyKey)
该方法用于获取目标对象指定属性的属性描述符,等价于Object.getOwnPropertyDescriptor,如果属性不存在则返回undefined。
const obj = { name: 'test' };
const descriptor = Reflect.getOwnPropertyDescriptor(obj, 'name');
console.log(descriptor); // 输出 { value: 'test', writable: true, enumerable: true, configurable: true }
11. Reflect.ownKeys(target)
该方法用于返回目标对象自身的所有键名,包括不可枚举属性和Symbol属性,返回结果是数组,等价于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))。
const sym = Symbol('key');
const obj = { a: 1, [sym]: 2 };
Object.defineProperty(obj, 'b', {
value: 3,
enumerable: false
});
const keys = Reflect.ownKeys(obj);
console.log(keys); // 输出 ['a', 'b', Symbol(key)]
12. Reflect.preventExtensions(target)
该方法用于让目标对象不可扩展,不能再添加新的属性,等价于Object.preventExtensions,操作成功返回true,失败返回false。
const obj = { x: 1 };
const preventResult = Reflect.preventExtensions(obj);
console.log(preventResult); // 输出 true
obj.y = 2;
console.log(obj.y); // 输出 undefined,添加属性失败
13. Reflect.isExtensible(target)
该方法用于判断目标对象是否可扩展,等价于Object.isExtensible,返回布尔值。
const obj1 = {};
const obj2 = Object.preventExtensions({});
console.log(Reflect.isExtensible(obj1)); // 输出 true
console.log(Reflect.isExtensible(obj2)); // 输出 false
Reflect的使用场景
Reflect最常见的使用场景是和Proxy配合实现对象代理,Proxy的陷阱方法可以直接调用对应的Reflect方法完成默认操作,减少重复代码。另外在一些需要动态操作对象、做统一的错误处理的场景中,使用Reflect的方法可以避免直接操作带来的错误抛出问题,让代码更加健壮。
需要注意的是,Reflect的方法参数如果不符合要求,比如第一个参数不是对象,大部分方法会直接抛出TypeError,使用前需要确保参数的合法性。
javascriptReflect反射元编程修改时间:2026-06-28 00:42:44