js 实现反射
反射的基本概念
反射是指在运行时动态获取和操作对象属性和方法的能力。JavaScript 提供了多种方式实现反射功能,主要通过内置对象和方法实现。
获取对象属性
使用 Object.keys() 可以获取对象所有可枚举属性的键名数组:
const obj = { a: 1, b: 2 };
const keys = Object.keys(obj); // ['a', 'b']
Object.getOwnPropertyNames() 会返回对象所有属性(包括不可枚举属性):
const obj = {};
Object.defineProperty(obj, 'hidden', { value: true, enumerable: false });
const props = Object.getOwnPropertyNames(obj); // ['hidden']
检查属性存在性
in 操作符可以检查对象或其原型链上是否存在指定属性:
const obj = { a: 1 };
console.log('a' in obj); // true
console.log('toString' in obj); // true(继承自原型)
Object.prototype.hasOwnProperty() 只检查对象自身属性:
const obj = { a: 1 };
console.log(obj.hasOwnProperty('a')); // true
console.log(obj.hasOwnProperty('toString')); // false
动态访问属性
使用方括号表示法可以动态访问属性:
const obj = { key: 'value' };
const propName = 'key';
console.log(obj[propName]); // 'value'
方法调用
可以通过字符串形式动态调用方法:
const obj = {
greet: function(name) { return `Hello ${name}`; }
};
const methodName = 'greet';
console.log(obj[methodName]('World')); // 'Hello World'
修改对象结构
Reflect API 提供了更完整的反射操作:
const obj = {};
Reflect.set(obj, 'key', 'value'); // 等价于 obj.key = 'value'
console.log(Reflect.get(obj, 'key')); // 'value'
原型操作
通过 Object.getPrototypeOf() 和 Object.setPrototypeOf() 可以操作原型链:
const parent = { inherited: true };
const child = {};
Object.setPrototypeOf(child, parent);
console.log(Object.getPrototypeOf(child) === parent); // true
构造函数调用
使用 Reflect.construct() 可以动态调用构造函数:
class Person {
constructor(name) { this.name = name; }
}
const instance = Reflect.construct(Person, ['Alice']);
console.log(instance.name); // 'Alice'
属性描述符操作
Object.getOwnPropertyDescriptor() 可以获取属性配置:
const obj = {};
Object.defineProperty(obj, 'readOnly', { value: 1, writable: false });
const desc = Object.getOwnPropertyDescriptor(obj, 'readOnly');
console.log(desc.writable); // false






