recursal/MDN huggingface dataset:
Symbol.prototype.toString()
===========================

概述
--

**`toString()`** 方法返回当前 symbol 对象的字符串表示。

语法
--
```

symbol.toString();
```

描述
--

`Symbol` 对象拥有自己的 `toString` 方法，因而遮蔽了原型链上的 `Object.prototype.toString()`。

### symbol 原始值不能转换为字符串

symbol 原始值不能转换为字符串，所以只能先转换成它的包装对象，再调用 `toString()` 方法：


```js
Symbol("foo") + "bar";
// TypeError: Can't convert symbol to string
Symbol("foo").toString() + "bar";
// "Symbol(foo)bar"，就相当于下面的：
Object(Symbol("foo")).toString() + "bar";
// "Symbol(foo)bar"
```

示例
--


```js
Symbol("desc").toString(); // "Symbol(desc)"

// 内置通用（well-known）symbol
Symbol.iterator.toString(); // "Symbol(Symbol.iterator)

// global symbols
Symbol.for("foo").toString(); // "Symbol(foo)"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-symbol.prototype.tostring |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Object.prototype.toString()`
Symbol.matchAll
===============

**`Symbol.matchAll`** 内置通用（well-known）符号指定方法返回一个迭代器，该迭代器根据字符串生成正则表达式的匹配项。此函数可以被 `String.prototype.matchAll()` 方法调用。

详细信息请参阅 `RegExp.prototype[@@matchAll]()` 和 `String.prototype.matchAll()`。

尝试一下
----

值
-

内置通用符号 `@@matchAll`。

| `Symbol.matchAll` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

示例
--

### 使用 Symbol.matchAll


```js
const str = "2016-01-02|2019-03-07";
const numbers = {
  \*[Symbol.matchAll](str) {
    for (const n of str.matchAll(/[0-9]+/g)) yield n[0];
  },
};
console.log(Array.from(str.matchAll(numbers)));
// ["2016", "01", "02", "2019", "03", "07"]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-symbol.matchall |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中 `Symbol.matchAll` 的 polyfill
* `String.prototype.matchAll()`
* `RegExp.prototype[@@matchAll]()`
Symbol.iterator
===============

**`Symbol.iterator`** 为每一个对象定义了默认的迭代器。该迭代器可以被 `for...of` 循环使用。

尝试一下
----

描述
--

当需要对一个对象进行迭代时（比如开始用于一个 `for..of` 循环中），它的 `@@iterator` 方法都会在不传参情况下被调用，返回的**迭代器**用于获取要迭代的值。

一些内置类型拥有默认的迭代器行为，其他类型（如 `Object`）则没有。拥有默认的 `@@iterator` 方法的内置类型是：

* `Array.prototype[@@iterator]()`
* `TypedArray.prototype[@@iterator]()`
* `String.prototype[@@iterator]()`
* `Map.prototype[@@iterator]()`
* `Set.prototype[@@iterator]()`

更多信息请参见迭代协议。

| `Symbol.iterator` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

示例
--

### 自定义迭代器

我们可以像下面这样创建自定义的迭代器：


```js
const myIterable = {};
myIterable[Symbol.iterator] = function\* () {
  yield 1;
  yield 2;
  yield 3;
};
[...myIterable]; // [1, 2, 3]
```


或者可以在类或对象中使用计算属性定义迭代：


```js
class Foo {
  \*[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  }
}

const someObj = {
  \*[Symbol.iterator]() {
    yield "a";
    yield "b";
  },
};

console.log(...new Foo()); // 1, 2, 3
console.log(...someObj); // 'a', 'b'
```

### 不符合标准的迭代器

如果一个迭代器 `@@iterator` 没有返回一个迭代器对象，那么它就是一个不符合标准的迭代器。这样的迭代器将会在运行期抛出异常，甚至出现非常诡异的 Bug：


```js
const nonWellFormedIterable = {};
nonWellFormedIterable[Symbol.iterator] = () => 1;
[...nonWellFormedIterable]; // TypeError: [Symbol.iterator]() returned a non-object value
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-symbol.iterator |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中 `Symbol.iterator` 的 Polyfill
* 迭代协议
* `Array.prototype[@@iterator]()`
* `TypedArray.prototype[@@iterator]()`
* `String.prototype[@@iterator]()`
* `Map.prototype[@@iterator]()`
* `Set.prototype[@@iterator]()`
Symbol.hasInstance
==================

**`Symbol.hasInstance`** 用于判断某对象是否为某构造器的实例。因此你可以用它自定义 `instanceof` 操作符在某个类上的行为。

尝试一下
----

| `Symbol.hasInstance` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

示例
--

你可实现一个自定义的`instanceof` 行为，例如：


```js
class MyArray {
  static [Symbol.hasInstance](instance) {
    return Array.isArray(instance);
  }
}
console.log([] instanceof MyArray); // true
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-symbol.hasinstance |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `instanceof`
Symbol.keyFor()
===============

概述
--

**`Symbol.keyFor(sym)`** 方法用来获取全局 symbol 注册表中与某个 symbol 关联的键。

语法
--
```

Symbol.keyFor(sym);
```

### 参数

sym

必选参数，需要查找键值的某个 Symbol。

### 返回值

如果全局注册表中查找到该 symbol，则返回该 symbol 的 key 值，返回值为字符串类型。否则返回 undefined

示例
--


```js
// 创建一个全局 Symbol
var globalSym = Symbol.for("foo");
Symbol.keyFor(globalSym); // "foo"

var localSym = Symbol();
Symbol.keyFor(localSym); // undefined，

// 以下 Symbol 不是保存在全局 Symbol 注册表中
Symbol.keyFor(Symbol.iterator); // undefined
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-symbol.keyfor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Symbol.prototype.for()`
Symbol.toStringTag
==================

**`Symbol.toStringTag`** 内置通用（well-known）symbol 是一个字符串值属性，用于创建对象的默认字符串描述。它由 `Object.prototype.toString()` 方法内部访问。

尝试一下
----

| `Symbol.toStringTag` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

示例
--

### 默认标签

一些值没有 `Symbol.toStringTag`，但是有额外的 `toString()` 表示。有关完整列表，请参见 `Object.prototype.toString()`。


```js
Object.prototype.toString.call("foo"); // "[object String]"
Object.prototype.toString.call([1, 2]); // "[object Array]"
Object.prototype.toString.call(3); // "[object Number]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
// ... and more
```

### 内置的 toStringTag symbol

大多数内置的对象提供了它们自己的 `@@toStringTag` 属性。所有内置对象的 `@@toStringTag` 属性都是不可写的（writable）、不可枚举的（enumerable）但是可配置的（configurable）。


```js
Object.prototype.toString.call(new Map()); // "[object Map]"
Object.prototype.toString.call(function\* () {}); // "[object GeneratorFunction]"
Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"
// ... and more
```

### 使用 toStringTag 自定义标签

当创建你自己的类时，JavaScript 默认用“Object”标签：


```js
class ValidatorClass {}

Object.prototype.toString.call(new ValidatorClass()); // "[object Object]"
```


现在，在 `toStringTag` 的帮助下，你可以设置自己的自定义标签：


```js
class ValidatorClass {
  get [Symbol.toStringTag]() {
    return "Validator";
  }
}

Object.prototype.toString.call(new ValidatorClass()); // "[object Validator]"
```

### toStringTag 适用于所有 DOM 原型对象

由于 2020 年年中 WebIDL 规范的变化，浏览器正在向所有 DOM 原型对象添加 `Symbol.toStringTag` 属性。例如，要访问 `HTMLButtonElement` 上的 `Symbol.toStringTag` 属性：


```js
const test = document.createElement("button");
test.toString(); // Returns [object HTMLButtonElement]
test[Symbol.toStringTag]; // Returns HTMLButtonElement
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-symbol.tostringtag |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中 `Symbol.toStringTag` 的 polyfill
* `Object.prototype.toString()`
Generator.prototype.throw()
===========================

`Generator` 实例的 **`throw()`** 方法的作用就好像一个 `throw` 语句被插入到生成器主体的当前暂停位置，这会通知生成器错误的情况并允许其处理错误，或者执行清理和自行关闭。

语法
--


```js
generatorInstance.throw(exception)
```

### 参数

`exception`

要抛出的异常。使用 `Error` 实例对调试非常有帮助。

### 返回值

如果抛出的异常被 `try...catch` 捕获并且生成器恢复生成更多的值，它将返回一个 `Object`，带有两个属性：

`done`

一个布尔值：

* 如果该生成器函数的控制流程已经结束，则为 `true`。
* 如果该生成器函数还能产生更多的值，则为 `false`。

`value`

下一个 `yeild` 表达式生成的值。

### 异常

如果抛出的错误没有被 `try...catch` 捕获，则传给 `throw()` 的 `exception` 将从生成器函数中抛出。

描述
--

`throw()` 方法在被调用时，可以看作是在生成器主体当前暂停的位置插入了一个 `throw exception;` 语句，其中 `exception` 是传入给 `throw()` 方法的异常。因此，在典型的流程中，调用 `throw(exception)` 将会导致生成器抛出异常。然而，如果 `yield` 表达式被包含在 `try...finally` 块中，错误可能会被捕获，并且控制流可以在错误处理后恢复，或者正常退出。

示例
--

### 使用 throw()

以下示例展示了一个简单生成器和使用 `throw` 方法抛出的错误。像往常一样，错误可以通过 `try...catch` 块捕获。


```js
function\* gen() {
  while (true) {
    try {
      yield 42;
    } catch (e) {
      console.log("捕获到错误！");
    }
  }
}

const g = gen();
g.next();
// { value: 42, done: false }
g.throw(new Error("出现了些问题"));
// "捕获到错误！"
// { value: 42, done: false }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator.prototype.throw |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `function*`
Generator.prototype.next()
==========================

`Generator` 实例的 **`next()`** 方法返回一个包含属性 `done` 和 `value` 的对象。你也可以通过向 `next` 方法传入一个参数来向生成器传一个值。

语法
--


```js
next()
next(value)
```

### 参数

`value` 可选

要传给生成器的值。

该值将作为 `yield` 表达式的结果。例如，在 `variable = yield expression` 中，传入给 `.next()` 函数的值将被分配给 `variable`。

### 返回值

一个 `Object`，包含以下两个属性：

`done`

一个布尔值：

* 如果生成器的控制流程已经结束，则为 `true`。在这种情况下，`value` 指定生成器的*返回值*（可能是 undefined）。
* 如果生成器还是产生更多的值，则为 `false`。

`value`

生成器产生或返回的任何 JavaScript 值。

示例
--

### 使用 next()

下面的例子展示了一个简单的生成器，以及调用 `next` 方法后的返回值：


```js
function\* gen() {
  yield 1;
  yield 2;
  yield 3;
}

const g = gen(); // Generator { }
g.next(); // { value: 1, done: false }
g.next(); // { value: 2, done: false }
g.next(); // { value: 3, done: false }
g.next(); // { value: undefined, done: true }
```

### 将 next() 与列表一起使用

在这个示例中，`getPage` 获取一个列表并将其按 `pageSize` 大小“分页”成块。每次调用 `next` 都会产生一个这样的块。


```js
function\* getPage(list, pageSize = 1) {
  for (let index = 0; index < list.length; index += pageSize) {
    yield list.slice(index, index + pageSize);
  }
}

const list = [1, 2, 3, 4, 5, 6, 7, 8];
const page = getPage(list, 3); // Generator { }

page.next(); // { value: [1, 2, 3], done: false }
page.next(); // { value: [4, 5, 6], done: false }
page.next(); // { value: [7, 8], done: false }
page.next(); // { value: undefined, done: true }
```

### 向生成器传值

在此示例中，调用 `next` 时传入值。

**备注：** 第一次调用不会打印任何内容，因为生成器最初没有产生任何内容。


```js
function\* gen() {
  while (true) {
    const value = yield;
    console.log(value);
  }
}

const g = gen();
g.next(1); // 返回 { value: undefined, done: false }
// 这一步不会有输出：通过 `next` 发送的第一个值会被丢弃
g.next(2); // 返回 { value: undefined, done: false }
// 打印 2
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator.prototype.next |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `function*`
* 迭代器和生成器指南
Generator.prototype.return()
============================

`Generator` 实例的 **`return()`** 方法的作用就好像一个 `return` 语句被插入到生成器主体的当前暂停位置，这会结束生成器并允许生成器与 `try...finally` 块结合使用时执行任何清理任务。

语法
--


```js
generatorInstance.return()
generatorInstance.return(value)
```

### 参数

`value` 可选

要返回的值。

### 返回值

一个 `Object`，有以下两个属性：

`done`

一个布尔值：

* 如果该生成器函数的控制流程已经结束，则为 `true`。
* 如果该生成器函数的控制流程还未结束并能产生更多的值，则为 `false`。只有在 `try...finally` 中捕获 `return` 并且 `finally` 块中还有更多的 `yield` 表达式时才会发生这种情况。

`value`

给定的作为参数的值，或者，如果 `yield` 表达式包含在 `try...finally`，从 `finally` 块产生/返回的值。

描述
--

`return()` 方法在被调用时，可以看作是在生成器主体当前暂停的位置插入了一个 `return value;` 语句，其中 `value` 是传入给 `return()` 方法的值。因此，在典型的流程中，调用 `return(value)` 将返回 `{done: true, value: value }`。然而，如果 `yield` 表达式被包含在 `try...finally` 块中，控制流不会退出函数体，而是进入 `finally` 块。在这种情况下，如果 `finally` 块中有更多 `yield` 表达式，返回的值可能会不同，`done` 甚至可能是 `false`。

示例
--

### 使用 return()

以下例子展示了一个简单的生成器和 `return` 方法的使用。


```js
function\* gen() {
  yield 1;
  yield 2;
  yield 3;
}

const g = gen();

g.next(); // { value: 1, done: false }
g.return("foo"); // { value: "foo", done: true }
g.next(); // { value: undefined, done: true }
```


如果对已经处于“完成”状态的生成器调用 `return(value)`，则生成器将保持在“完成”状态。

如果没有提供参数，则返回对象的 `value` 将为 `undefined`。如果提供了参数，则参数将被设置为返回对象的 `value` 属性的值，除非 `yield` 表达式被包装在 `try...finally` 中。


```js
function\* gen() {
  yield 1;
  yield 2;
  yield 3;
}

const g = gen();
g.next(); // { value: 1, done: false }
g.next(); // { value: 2, done: false }
g.next(); // { value: 3, done: false }
g.next(); // { value: undefined, done: true }
g.return(); // { value: undefined, done: true }
g.return(1); // { value: 1, done: true }
```

### 将 return() 与 try...finally 一起使用

如果 `yield` 表达式被包含在一个 `try...finally` 块中，只有生成器本身才能知道 `return` 方法已被调用。

当在 `try` 块中暂停的生成器上调用 `return` 方法时，生成器中的执行将继续到 `finally` 块——因为 `try...finally` 语句的 `finally` 块始终执行。


```js
function\* gen() {
  yield 1;
  try {
    yield 2;
    yield 3;
  } finally {
    yield "cleanup";
  }
}

const g1 = gen();
g1.next(); // { value: 1, done: false }

// 在 try...finally 前暂停执行。
g1.return("early return"); // { value: 'early return', done: true }

const g2 = gen();
g2.next(); // { value: 1, done: false }
g2.next(); // { value: 2, done: false }

// 在 try...finally 中暂停执行。
g2.return("early return"); // { value: 'cleanup', done: false }

// 完成值被保留
g2.next(); // { value: 'early return', done: true }

// 生成器处于完成状态
g2.return("not so early return"); // { value: 'not so early return', done: true }
```


finally 块的返回值也可以成为 `return` 调用返回结果的 `value`。


```js
function\* gen() {
  try {
    yield 1;
  } finally {
    return "cleanup";
  }
}

const g1 = gen();
g1.next(); // { value: 1, done: false }
g1.return("early return"); // { value: 'cleanup', done: true }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator.prototype.return |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `function*`
GeneratorFunction() 构造函数
========================

**`GeneratorFunction()`** 构造函数创建 `GeneratorFunction` 对象。

请注意，`GeneratorFunction` *不是*全局对象。可以通过以下代码来获取它：


```js
const GeneratorFunction = function\* () {}.constructor;
```


`GeneratorFunction()` 构造函数不能直接使用，并且所有在 `Function()` 描述中提到的注意事项都适用于 `GeneratorFunction()`。

语法
--


```js
new GeneratorFunction(functionBody)
new GeneratorFunction(arg1, functionBody)
new GeneratorFunction(arg1, arg2, functionBody)
new GeneratorFunction(arg1, arg2, /\* …, \*/ argN, functionBody)

GeneratorFunction(functionBody)
GeneratorFunction(arg1, functionBody)
GeneratorFunction(arg1, arg2, functionBody)
GeneratorFunction(arg1, arg2, /\* …, \*/ argN, functionBody)
```


**备注：** 无论是否使用 `new` 调用 `GeneratorFunction()`，都可以创建一个新的 `GeneratorFunction` 实例。

### 参数

参见 `Function()`。

示例
--

### 创建和使用 GeneratorFunction() 构造函数


```js
const GeneratorFunction = function\* () {}.constructor;
const g = new GeneratorFunction("a", "yield a \* 2");
const iterator = g(10);
console.log(iterator.next().value); // 20
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-generatorfunction-constructor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `function*`
* `function*` 表达式
* `Function()` 构造函数
* 迭代器和生成器指南
* Functions
Reflect.isExtensible()
======================

`静态方法 Reflect`**`.isExtensible()`** 判断一个对象是否可扩展（即是否能够添加新的属性）。与它 `Object.isExtensible()` 方法相似，但有一些不同，详情可见 与 Object.isExtensible() 的不同点。

语法
--
```

Reflect.isExtensible(target)
```

### 参数

`target`

检查是否可扩展的目标对象。

### 返回值

返回一个 `Boolean` 值表明该对象是否可扩展。

### 异常

抛出一个 `TypeError`，如果对象不是 `Object`。

描述
--

`Reflect.isExtensible 判断`一个对象是否可扩展（即是否能够添加新的属性）。它与 `Object.isExtensible()` 方法一样。

示例
--

### 使用 `Reflect.isExtensible()`

详情可见 `Object.isExtensible()`。


```js
// New objects are extensible.
var empty = {};
Reflect.isExtensible(empty); // === true

// ...but that can be changed.
Reflect.preventExtensions(empty);
Reflect.isExtensible(empty); // === false

// Sealed objects are by definition non-extensible.
var sealed = Object.seal({});
Reflect.isExtensible(sealed); // === false

// Frozen objects are also by definition non-extensible.
var frozen = Object.freeze({});
Reflect.isExtensible(frozen); // === false
```

### 与 `Object.isExtensible()` 的不同点

如果该方法的第一个参数不是一个对象（原始值），那么将造成一个 `TypeError` 异常。对于 `Object.isExtensible()`，非对象的第一个参数会被强制转换为一个对象。


```js
Reflect.isExtensible(1);
// TypeError: 1 is not an object

Object.isExtensible(1);
// false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.isextensible |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Reflect`
* `Object.isExtensible()`
Reflect.has()
=============

静态方法 **`Reflect.has()`** 作用与 `in` 操作符 相同。

句法
--
```

Reflect.has(target, propertyKey)
```

### 参数

`target`

目标对象。

`propertyKey`

属性名，需要检查目标对象是否存在此属性。

### 返回值

一个 `Boolean` 类型的对象指示是否存在此属性。

### 异常

如果目标对象并非`Object` 类型，抛出`TypeError`。

描述
--

`Reflect.has` 用于检查一个对象是否拥有某个属性，相当于`in` 操作符 。

示例
--

### 使用 `Reflect.has()`


```js
Reflect.has({ x: 0 }, "x"); // true
Reflect.has({ x: 0 }, "y"); // false

// 如果该属性存在于原型链中，返回 true
Reflect.has({ x: 0 }, "toString");

// Proxy 对象的 .has() 句柄方法
obj = new Proxy(
  {},
  {
    has(t, k) {
      return k.startsWith("door");
    },
  },
);
Reflect.has(obj, "doorbell"); // true
Reflect.has(obj, "dormitory"); // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.has |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

相关连接
----

* `Reflect`
* `in` operator
Reflect.get()
=============

**`Reflect.get()`** 方法与从 对象 (`target[propertyKey]`) 中读取属性类似，但它是通过一个函数执行来操作的。

语法
--
```

Reflect.get(target, propertyKey[, receiver])
```

### 参数

`target`

需要取值的目标对象

`propertyKey`

需要获取的值的键值

receiver

如果`target`对象中指定了`getter`，`receiver`则为`getter`调用时的`this`值。

### 返回值

属性的值。

### 异常

如果目标值类型不是 `Object`，则抛出一个 `TypeError`。

描述
--

`Reflect.get`方法允许你从一个对象中取属性值。就如同属性访问器 语法，但却是通过函数调用来实现。

示例
--

### `使用 Reflect.get()`


```js
// Object
var obj = { x: 1, y: 2 };
Reflect.get(obj, "x"); // 1

// Array
Reflect.get(["zero", "one"], 1); // "one"

// Proxy with a get handler
var x = { p: 1 };
var obj = new Proxy(x, {
  get(t, k, r) {
    return k + "bar";
  },
});
Reflect.get(obj, "foo"); // "foobar"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.get |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Reflect`
* 属性访问器
Reflect.getOwnPropertyDescriptor()
==================================

静态方法 **`Reflect.getOwnPropertyDescriptor()`** 与 `Object.getOwnPropertyDescriptor()` 方法相似。如果在对象中存在，则返回给定的属性的属性描述符。否则返回 `undefined`。

语法
--
```

Reflect.getOwnPropertyDescriptor(target, propertyKey)
```

### 参数

`target`

需要寻找属性的目标对象。

`propertyKey`

获取自己的属性描述符的属性的名称。

### 返回值

如果属性存在于给定的目标对象中，则返回属性描述符；否则，返回 `undefined`。

### 异常

抛出一个 `TypeError`，如果目标不是 `Object`。

描述
--

`Reflect.getOwnPropertyDescriptor`方法返回一个属性描述符，如果给定的属性存在于对象中，否则返回 `undefined` 。与 `Object.getOwnPropertyDescriptor()` 的唯一不同在于如何处理非对象目标。

示例
--

### 使用 `Reflect.getOwnPropertyDescriptor()`


```js
Reflect.getOwnPropertyDescriptor({ x: "hello" }, "x");
// {value: "hello", writable: true, enumerable: true, configurable: true}

Reflect.getOwnPropertyDescriptor({ x: "hello" }, "y");
// undefined

Reflect.getOwnPropertyDescriptor([], "length");
// {value: 0, writable: true, enumerable: false, configurable: false}
```

### 与 `Object.getOwnPropertyDescriptor() 的不同点`

如果该方法的第一个参数不是一个对象（一个原始值），那么将造成 `TypeError` 错误。而对于 `Object.getOwnPropertyDescriptor`，非对象的第一个参数将被强制转换为一个对象处理。


```js
Reflect.getOwnPropertyDescriptor("foo", 0);
// TypeError: "foo" is not non-null object

Object.getOwnPropertyDescriptor("foo", 0);
// { value: "f", writable: false, enumerable: true, configurable: false }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.getownpropertydescriptor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Reflect`
* `Object.getOwnPropertyDescriptor()`
Reflect.setPrototypeOf()
========================

除了返回类型以外，静态方法 **`Reflect.setPrototypeOf()`** 与 `Object.setPrototypeOf()` 方法是一样的。它可设置对象的原型（即内部的 `[[Prototype]]` 属性）为另一个对象或 `null`，如果操作成功返回 `true`，否则返回 `false`。

尝试一下
----

语法
--
```

Reflect.setPrototypeOf(target, prototype)
```

### 参数

*`target`*

设置原型的目标对象。

*`prototype`*

对象的新原型（一个对象或 `null`）。

### 返回值

返回一个 `Boolean` 值表明是否原型已经成功设置。

### 异常

如果 *`target`* 不是 `Object` ，或 \*`prototype` \*既不是对象也不是 `null`，抛出一个 `TypeError` 异常。

描述
--

`Reflect.setPrototypeOf` 方法改变指定对象的原型（即，内部的 `[[Prototype]]` 属性值）。

示例
--

### 使用 `Reflect.setPrototypeOf()`


```js
Reflect.setPrototypeOf({}, Object.prototype); // true

// It can change an object's [[Prototype]] to null.
Reflect.setPrototypeOf({}, null); // true

// Returns false if target is not extensible.
Reflect.setPrototypeOf(Object.freeze({}), null); // false

// Returns false if it cause a prototype chain cycle.
var target = {};
var proto = Object.create(target);
Reflect.setPrototypeOf(target, proto); // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.setprototypeof |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Reflect`
* `Object.setPrototypeOf()`
Reflect.apply()
===============

静态方法 **`Reflect.apply()`** 通过指定的参数列表发起对目标 (target) 函数的调用。

尝试一下
----

语法
--
```

Reflect.apply(target, thisArgument, argumentsList)
```

### 参数

target

目标函数。

thisArgument

target 函数调用时绑定的 this 对象。

argumentsList

target 函数调用时传入的实参列表，该参数应该是一个类数组的对象。

### 返回值

返回值是调用完带着指定参数和 `this` 值的给定的函数后返回的结果。

### 异常

如果 `target` 对象不可调用，抛出 `TypeError`。

描述
--

该方法与 ES5 中`Function.prototype.apply()`方法类似：调用一个方法并且显式地指定 `this` 变量和参数列表 (arguments) ，参数列表可以是数组，或类似数组的对象。


```js
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
```


使用 `Reflect.apply` 方法会使代码更加简洁易懂。

使用示例
----

### `Reflect.apply()`


```js
Reflect.apply(Math.floor, undefined, [1.75]);
// 1;

Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
// "hello"

Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;
// 4

Reflect.apply("".charAt, "ponies", [3]);
// "i"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.apply |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

相关连接
----

* `Reflect`
* `Function.prototype.apply()`
Reflect.preventExtensions()
===========================

静态方法 **`Reflect.preventExtensions()`** 方法阻止新属性添加到对象 (例如：防止将来对对象的扩展被添加到对象中)。该方法与 `Object.preventExtensions()`相似，但有一些不同点。详情可见 differences。

尝试一下
----

语法
--
```

Reflect.preventExtensions(target)
```

### 参数

`target`

阻止扩展的目标对象。

### 返回值

返回一个 `Boolean` 值表明目标对象是否成功被设置为不可扩展。

### 异常

抛出一个 `TypeError` 错误，如果 `target` 不是 `Object`。

描述
--

`Reflect.preventExtensions` 方法阻止新属性添加到对象 (例如：防止将来对对象的扩展被添加到对象中)。该方法与 `Object.preventExtensions()` 方法相似。

示例
--

### 使用 `Reflect.preventExtensions()`

详情可见 `Object.preventExtensions()`.


```js
// Objects are extensible by default.
var empty = {};
Reflect.isExtensible(empty); // === true

// ...but that can be changed.
Reflect.preventExtensions(empty);
Reflect.isExtensible(empty); // === false
```

### 与 `Object.preventExtensions()` 的不同点

如果该方法的 *`target`* 参数不是一个对象（是原始值），那么将造成一个 `TypeError` 异常。对于`Object.preventExtensions()` 方法，非对象的 *`target`* 参数将被强制转换为对象。


```js
Reflect.preventExtensions(1);
// TypeError: 1 is not an object

Object.preventExtensions(1);
// 1
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.preventextensions |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Reflect`
* `Object.isExtensible()`