# 十六、反射 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)`