js 实现反射
反射的基本概念
反射(Reflection)是指在运行时检查、访问和修改对象的结构和行为的能力。JavaScript 虽然没有像 Java 或 C# 那样内置完整的反射 API,但可以通过一些内置方法和特性实现类似功能。
获取对象的属性和方法
使用 Object.keys()、Object.getOwnPropertyNames() 或 Reflect.ownKeys() 可以获取对象的属性列表。
const obj = { a: 1, b: 2 };
console.log(Object.keys(obj)); // ["a", "b"]
console.log(Reflect.ownKeys(obj)); // ["a", "b"]
动态访问属性
通过字符串名称动态访问对象的属性,可以使用 [] 或 Reflect.get()。

const obj = { a: 1, b: 2 };
const propName = 'a';
console.log(obj[propName]); // 1
console.log(Reflect.get(obj, propName)); // 1
动态调用方法
使用 Function.prototype.apply() 或 Reflect.apply() 动态调用方法。
const obj = {
greet: function(name) {
return `Hello, ${name}!`;
}
};
const methodName = 'greet';
console.log(obj[methodName].apply(obj, ['Alice'])); // "Hello, Alice!"
console.log(Reflect.apply(obj[methodName], obj, ['Bob'])); // "Hello, Bob!"
检查对象类型
使用 typeof、instanceof 或 Object.prototype.toString.call() 检查对象的类型。

const value = [1, 2, 3];
console.log(typeof value); // "object"
console.log(value instanceof Array); // true
console.log(Object.prototype.toString.call(value)); // "[object Array]"
修改对象行为
通过 Object.defineProperty() 或 Reflect.defineProperty() 动态修改对象的属性行为。
const obj = {};
Reflect.defineProperty(obj, 'x', {
value: 42,
writable: false
});
console.log(obj.x); // 42
obj.x = 100; // 静默失败(严格模式下会报错)
console.log(obj.x); // 42
创建代理对象
使用 Proxy 对象可以对目标对象的操作进行拦截和自定义。
const target = { a: 1 };
const handler = {
get: function(target, prop) {
return prop in target ? target[prop] : 0;
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.a); // 1
console.log(proxy.b); // 0
反射 API(ES6)
ES6 引入了 Reflect 对象,提供了一组静态方法用于反射操作。
const obj = { a: 1 };
console.log(Reflect.has(obj, 'a')); // true
console.log(Reflect.set(obj, 'b', 2)); // true
console.log(obj.b); // 2
通过这些方法,JavaScript 可以实现灵活的反射功能,适用于动态代码生成、元编程等场景。






