# 十六、反射 API 反射应用编程接口为对象提供运行时级别的元操作。这实际上与代理应用编程接口相反,允许调用与代理陷阱相同的元操作。`Reflect`对象是静态对象。您不能创建它的实例。同样,它的所有方法都是静态的。你可能认为我们已经有了一些类似 JavaScript 的反射方法,但是最大的区别是`Reflect`提供了更有意义的返回值。 考虑以下示例: 代码清单 208 ```js let obj = {}, name = "matt", desc = "here we go"; try { Object.defineProperty(obj, name, desc); // worked. } catch (e) { // error. } if (Reflect.defineProperty(obj, name, desc)) { // worked } else { // error. } ``` 在第一部分中,我们有一个 try/catch 块,我们使用的是`Object.defineProperty`方法。在这个例子中,这个方法只返回传递给它的第一个参数。但是,看一下`Reflect.defineProperty`方法,我们看到它返回了一个布尔值,这要有意义得多。 让我们考虑另一个例子: 代码清单 209 ```js let obj = { a: 1 }; Object.defineProperty(obj, "b", { value: 2 }); obj[Symbol("c")] = 3; console.log(Reflect.ownKeys(obj)); // [ "a", "b", Symbol(c) ] ``` 如您在本例中所见,`Reflect.ownKeys`为我们提供了基于字符串和符号的键。 以下是`Reflect`对象包含的所有方法: * `Reflect.get(target, name, [receiver])` * `Reflect.set(target, name, value, [receiver])` * `Reflect.has(target, name)` * `Reflect.apply(target, receiver, args)` * `Reflect.construct(target, args)` * `Reflect.getOwnPropertyDescriptor(target, name)` * `Reflect.defineProperty(target, name, desc)` * `Reflect.getPrototypeOf(target)` * `Reflect.setPrototypeOf(target, newProto)` * `Reflect.deleteProperty(target, name)` * `Reflect.enumerate(target)` * `Reflect.preventExtensions(target)` * `Reflect.isExtensible(target)` * `Reflect.ownKeys(target)`