recursal/MDN huggingface dataset:
Reflect.defineProperty()
========================

静态方法 **`Reflect.defineProperty()`** 基本等同于 `Object.defineProperty()` 方法，唯一不同是返回 `Boolean` 值。

语法
--
```

Reflect.defineProperty(target, propertyKey, attributes)
```

### 参数

`target`

目标对象。

`propertyKey`

要定义或修改的属性的名称。

`attributes`

要定义或修改的属性的描述。

### 返回值

`Boolean` 值指示了属性是否被成功定义。

### 异常

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

描述
--

`Reflect.defineProperty` 方法允许精确添加或修改对象上的属性。更多的细节请参阅类似的`Object.defineProperty` 。

**备注：** `Object.defineProperty` 返回一个对象，或者如果属性没有被成功定义，抛出一个 `TypeError`。相比之下，`Reflect.defineProperty` 方法只返回一个 `Boolean`，来说明该属性是否被成功定义。

示例
--

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

let obj = {}
Reflect.defineProperty(obj, 'x', {value: 7})  // true
obj.x                                         // 7
```

### 检查属性是否被成功定义

`Object.defineProperty` 方法，如果成功则返回一个对象，否则抛出一个 `TypeError` 。另外，当定义一个属性时，你也可以使用 `try...catch` 去捕获其中任何的错误。而因为 `Reflect.defineProperty` 返回 Boolean 值作为成功的标识，所以只能使用 `if...else` ：


```js
if (Reflect.defineProperty(target, property, attributes)) {
  // 成功
} else {
  // 失败
}
```

规范
--

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

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

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

参见
--

* `Reflect`
* `Object.defineProperty()`
Reflect.construct()
===================

**`Reflect.construct()`** 方法的行为有点像 `new` 操作符 构造函数，相当于运行 `new target(...args)`.

语法
--
```

Reflect.construct(target, argumentsList[, newTarget])
```

### 参数

`target`

被运行的目标构造函数

`argumentsList`

类数组，目标构造函数调用时的参数。

`newTarget` 可选

作为新创建对象的原型对象的 `constructor` 属性，参考 `new.target` 操作符，默认值为 `target`。

### `返回值`

以`target`（如果`newTarget`存在，则为`newTarget`）函数为构造函数，`argumentList`为其初始化参数的对象实例。

### 异常

如果 target 或者 newTarget 不是构造函数，抛出`TypeError`,异常。

描述
--

`Reflect.construct`允许你使用可变的参数来调用构造函数，这和使用new 操作符搭配对象展开符调用一样。


```js
var obj = new Foo(...args);
var obj = Reflect.construct(Foo, args);
```

### `Reflect.construct()` vs `Object.create()`

`在新语法 Reflect`出现之前，是通过明确指定构造函数和原型对象（使用`Object.create()`）来创建一个对象的。


```js
function OneClass() {
  this.name = "one";
}

function OtherClass() {
  this.name = "other";
}

// 创建一个对象：
var obj1 = Reflect.construct(OneClass, args, OtherClass);

// 与上述方法等效：
var obj2 = Object.create(OtherClass.prototype);
OneClass.apply(obj2, args);

console.log(obj1.name); // 'one'
console.log(obj2.name); // 'one'

console.log(obj1 instanceof OneClass); // false
console.log(obj2 instanceof OneClass); // false

console.log(obj1 instanceof OtherClass); // true
console.log(obj2 instanceof OtherClass); // true
```


虽然两种方式结果相同，但在创建对象过程中仍一点不同。

当使用`Object.create()`和`Function.prototype.apply()`时，如果不使用`new`操作符调用构造函数，构造函数内部的`new.target`值会指向`undefined`。

当调用`Reflect.construct()`来创建对象，`new.target`值会自动指定到`target`（或者 newTarget，前提是 newTarget 指定了）。


```js
function OneClass() {
  console.log("OneClass");
  console.log(new.target);
}
function OtherClass() {
  console.log("OtherClass");
  console.log(new.target);
}

var obj1 = Reflect.construct(OneClass, args);
// 输出：
// OneClass
// function OneClass { ... }

var obj2 = Reflect.construct(OneClass, args, OtherClass);
// 输出：
// OneClass
// function OtherClass { ... }

var obj3 = Object.create(OtherClass.prototype);
OneClass.apply(obj3, args);
// 输出：
// OneClass
// undefined
```

示例
--

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


```js
var d = Reflect.construct(Date, [1776, 6, 4]);
d instanceof Date; // true
d.getFullYear(); // 1776
```

规范
--

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

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

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

参见
--

* `Reflect`
* `new`
* `new.target`
Reflect.set()
=============

静态方法 **`Reflect.set()`** 工作方式就像在一个对象上设置一个属性。

语法
--
```

Reflect.set(target, propertyKey, value[, receiver])
```

### 参数

`target`

设置属性的目标对象。

`propertyKey`

设置的属性的名称。

`value`

设置的值。

`receiver`

如果遇到 `setter`，`receiver`则为`setter`调用时的`this`值。

### 返回值

返回一个 `Boolean` 值表明是否成功设置属性。

### 异常

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

描述
--

`Reflect.set` 方法允许你在对象上设置属性。它的作用是给属性赋值并且就像 property accessor 语法一样，但是它是以函数的方式。

示例
--

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


```js
// Object
var obj = {};
Reflect.set(obj, "prop", "value"); // true
obj.prop; // "value"

// Array
var arr = ["duck", "duck", "duck"];
Reflect.set(arr, 2, "goose"); // true
arr[2]; // "goose"

// It can truncate an array.
Reflect.set(arr, "length", 1); // true
arr; // ["duck"];

// With just one argument, propertyKey and value are "undefined".
var obj = {};
Reflect.set(obj); // true
Reflect.getOwnPropertyDescriptor(obj, "undefined");
// { value: undefined, writable: true, enumerable: true, configurable: true }
```

规范
--

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

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

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

参见
--

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

静态方法 **`Reflect.deleteProperty()`** 允许用于删除属性。它很像 `delete` operator ，但它是一个函数。

语法
--
```

Reflect.deleteProperty(target, propertyKey)
```

### 参数

`target`

删除属性的目标对象。

`propertyKey`

需要删除的属性的名称。

### 返回值

`Boolean` 值表明该属性是否被成功删除。

### 异常

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

描述
--

`Reflect.deleteProperty` 允许你删除一个对象上的属性。返回一个 `Boolean` 值表示该属性是否被成功删除。它几乎与非严格的 `delete` operator 相同。

示例
--

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


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

var arr = [1, 2, 3, 4, 5];
Reflect.deleteProperty(arr, "3"); // true
arr; // [1, 2, 3, , 5]

// 如果属性不存在，返回 true
Reflect.deleteProperty({}, "foo"); // true

// 如果属性不可配置，返回 false
Reflect.deleteProperty(Object.freeze({ foo: 1 }), "foo"); // false
```

规范
--

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

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

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

参见
--

* `core-js` 中 `Reflect.deleteProperty` 的 polyfill
* `Reflect`
* `delete`
* `handler.deleteProperty()`
Reflect.getPrototypeOf()
========================

静态方法 **`Reflect.getPrototypeOf()`** 与 `Object.getPrototypeOf()` 方法几乎是一样的。都是返回指定对象的原型（即内部的 `[[Prototype]]` 属性的值）。

尝试一下
----

语法
--
```

Reflect.getPrototypeOf(target)
```

### 参数

`target`

获取原型的目标对象。

### 返回值

给定对象的原型。如果给定对象没有继承的属性，则返回 `null`。

### 异常

如果 `target` 不是 `Object`，抛出一个 `TypeError` 异常。

描述
--

`Reflect.getPrototypeOf` 返回指定对象的原型 (即内部的 `[[Prototype]]` 属性的值) 。

示例
--

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


```js
Reflect.getPrototypeOf({}); // Object.prototype
Reflect.getPrototypeOf(Object.prototype); // null
Reflect.getPrototypeOf(Object.create(null)); // null
```

### 与 `Object.getPrototypeOf()` 比较
```

// 如果参数为 Object，返回结果相同
Object.getPrototypeOf({})   // Object.prototype
Reflect.getPrototypeOf({})  // Object.prototype

// 在 ES5 规范下，对于非 Object，抛异常
Object.getPrototypeOf('foo')   // Throws TypeError
Reflect.getPrototypeOf('foo')  // Throws TypeError

// 在 ES2015 规范下，Reflect 抛异常，Object 强制转换非 Object
Object.getPrototypeOf('foo')   // String.prototype
Reflect.getPrototypeOf('foo')  // Throws TypeError

// 如果想要模拟 Object 在 ES2015 规范下的表现，需要强制类型转换
Reflect.getPrototypeOf(Object('foo'))  // String.prototype
```

规范
--

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

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

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

参见
--

* `Reflect`
* `Object.getPrototypeOf()`
Reflect.ownKeys()
=================

静态方法 **`Reflect.ownKeys()`** 返回一个由目标对象自身的属性键组成的数组。

尝试一下
----

语法
--
```

Reflect.ownKeys(target)
```

### 参数

`target`

获取自身属性键的目标对象。

### 返回值

由目标对象的自身属性键组成的 `Array`。

### 异常

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

描述
--

`Reflect.ownKeys` 方法返回一个由目标对象自身的属性键组成的数组。它的返回值等同于 ``Object.getOwnPropertyNames`(target).concat(`Object.getOwnPropertySymbols`(target))`。

示例
--

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


```js
Reflect.ownKeys({ z: 3, y: 2, x: 1 }); // [ "z", "y", "x" ]
Reflect.ownKeys([]); // ["length"]

var sym = Symbol.for("comet");
var sym2 = Symbol.for("meteor");
var obj = {
  [sym]: 0,
  str: 0,
  773: 0,
  0: 0,
  [sym2]: 0,
  "-1": 0,
  8: 0,
  "second str": 0,
};
Reflect.ownKeys(obj);
// [ "0", "8", "773", "str", "-1", "second str", Symbol(comet), Symbol(meteor) ]
// Indexes in numeric order,
// strings in insertion order,
// symbols in insertion order
```

规范
--

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

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

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

参见
--

* `Reflect`
* `Object.getOwnPropertyNames()`
getter
======

**`get`** 语法将对象属性绑定到查询该属性时将被调用的函数。

尝试一下
----

语法
--
```

{get prop() { ... } }

{get [expression]() { ... } }
```

### 参数

`prop`

要绑定到给定函数的属性名。

expression

从 ECMAScript 2015 开始，还可以使用一个计算属性名的表达式绑定到给定的函数。

描述
--

有时需要允许访问返回动态计算值的属性，或者你可能需要反映内部变量的状态，而不需要使用显式方法调用。在 JavaScript 中，可以使用 *getter* 来实现。

尽管可以结合使用 getter 和 setter 来创建一个伪属性，但是不可能同时将一个 getter 绑定到一个属性并且该属性实际上具有一个值。

使用`get`语法时应注意以下问题：

* 可以使用数值或字符串作为标识；
* 必须不带参数（请参考Incompatible ES5 change: literal getter and setter functions must now have exactly zero or one arguments）；
* 它不能与另一个 `get` 或具有相同属性的数据条目同时出现在一个对象字面量中（不允许使用 `{ get x() { }, get x() { } }` 和 `{ x: ..., get x() { } }`）。
示例
--

### 在新对象初始化时定义一个 getter

这会为`obj`创建一个伪属性`latest`，它会返回`log`数组的最后一个元素。


```js
const obj = {
  log: ["example", "test"],
  get latest() {
    if (this.log.length == 0) return undefined;
    return this.log[this.log.length - 1];
  },
};
console.log(obj.latest); // "test".
```


注意，尝试为`latest`分配一个值不会改变它。

### 使用`delete`操作符删除 getter

只需使用 `delete`，就可删除 getter：


```js
delete obj.latest;
```

### 使用`defineProperty`在现有对象上定义 getter

要随时将 getter 添加到现有对象，使用 `Object.defineProperty()`.


```js
var o = { a: 0 };

Object.defineProperty(o, "b", {
  get: function () {
    return this.a + 1;
  },
});

console.log(o.b); // Runs the getter, which yields a + 1 (which is 1)
```

### 使用计算出的属性名


```js
var expr = "foo";

var obj = {
  get [expr]() {
    return "bar";
  },
};

console.log(obj.foo); // "bar"
```

### 智能 / 自我复写/ 懒加载 getters

Getters 给你一种方法来定义一个对象的属性，但是在访问它们之前不会计算属性的值。getter 延迟计算值的成本，直到需要此值，如果不需要，你就不用支付成本。

一种额外的优化技术是用**智能 (或称记忆化)getters** 延迟属性值的计算并将其缓存以备以后访问。该值是在第一次调用 getter 时计算的，然后被缓存，因此后续访问返回缓存值而不重新计算它。这在以下情况下很有用：

* 如果属性值的计算是昂贵的（占用大量 RAM 或 CPU 时间，产生工作线程，检索远程文件等）。
* 如果现在不需要该值。它将在稍后使用，或在某些情况下它根本不使用。
* 如果被使用，它将被访问几次，并且不需要重新计算，该值将永远不会被改变，或者不应该被重新计算。

**备注：** 这意味着你不应该为你希望更改其值的属性使用懒 getter，因为 getter 不会重新计算该值。

在以下示例中，对象具有一个 getter 属性。在获取属性时，该属性将从对象中删除并重新添加，但此时将隐式显示为数据属性。最后返回得到值。


```js
get notifier() {
  delete this.notifier;
  return this.notifier = document.getElementById('bookmarked-notification-anchor');
},
```


对于 Firefox 代码，另请参阅定义`defineLazyGetter()` 函数的`XPCOMUtils.jsm`代码模块。

### `get` vs. `defineProperty`

当使用 `get` 关键字时，它和`Object.defineProperty()` 有类似的效果，在`classes`中使用时，二者有细微的差别。

当使用 `get` 关键字时，属性将被定义在实例的原型上，当使用`Object.defineProperty()`时，属性将被定义在实例自身上。


```js
class Example {
  get hello() {
    return "world";
  }
}

const obj = new Example();
console.log(obj.hello);
// "world"

console.log(Object.getOwnPropertyDescriptor(obj, "hello"));
// undefined

console.log(
  Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), "hello"),
);
// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-method-definitions |

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

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

参见
--

* setter
* `delete`
* `Object.defineProperty()`
* `Object.prototype.__defineGetter__()`
* `Object.prototype.__defineSetter__()`
* 在 Javascript 指南中 定义 Getter 和 Setter
方法的定义
=====

从 ECMAScript 2015 开始，在对象初始器中引入了一种更简短定义方法的语法，这是一种把方法名直接赋给函数的简写方式。

尝试一下
----

语法
--
```

var obj = {
  property( parameters… ) {},
  *generator( parameters… ) {},
  async property( parameters… ) {},
  async* generator( parameters… ) {},

  // with computed keys:
  [property]( parameters… ) {},
  *[generator]( parameters… ) {},
  async [property]( parameters… ) {},

  // compare getter/setter syntax:
  get property() {},
  set property(value) {}
};
```

描述
--

该简写语法与 ECMAScript 2015 的getter和setter语法类似。

如下代码：


```js
var obj = {
  foo: function () {
    /\* code \*/
  },
  bar: function () {
    /\* code \*/
  },
};
```


现可被简写为：


```js
var obj = {
  foo() {
    /\* code \*/
  },
  bar() {
    /\* code \*/
  },
};
```


**备注：** 简写语法使用具名函数而不是匿名函数（如…`foo: function() {}`…）。具名函数可以从函数体调用（这对匿名函数是不可能的，因为没有标识符可以引用）。详细信息，请参阅`function`。

### 生成器方法

生成器方法也可以用这种简写语法定义。使用它们时，

* 简写语法中的星号（\*）必须出现在生成器名前，也就是说`* g(){}`可以正常工作，而`g *(){}`不行。
* 非生成器方法定义可能不包含`yield`关键字。这意味着遗留的生成器函数 (en-US)也不会工作，并且将抛出 `SyntaxError`。始终使用`yield`与星号（\*）结合使用。


```js
// 用有属性名的语法定义方法（ES6 之前）：
var obj2 = {
  g: function\* () {
    var index = 0;
    while (true) yield index++;
  },
};

// 同一个方法，简写语法：
var obj2 = {
  \*g() {
    var index = 0;
    while (true) yield index++;
  },
};

var it = obj2.g();
console.log(it.next().value); // 0
console.log(it.next().value); // 1
```

### Async 方法

Async 方法也可以使用简写语法来定义。


```js
// 用有属性名的语法定义方法（ES6 之前）：
var obj3 = {
  f: async function () {
    await some_promise;
  },
};

// 同一个方法，简写语法：
var obj3 = {
  async f() {
    await some_promise;
  },
};
```

### Async 生成器方法

生成器方法也能成为 async.


```js
var obj4 = {
  f: async function\* () {
    yield 1;
    yield 2;
    yield 3;
  },
};

// The same object using shorthand syntax
var obj4 = {
  async \*f() {
    yield 1;
    yield 2;
    yield 3;
  },
};
```

### 方法定义不是构造函数

所有方法定义不是构造函数，如果你尝试实例化它们，将抛出`TypeError`。


```js
var obj = {
  method() {},
};
new obj.method(); // TypeError: obj.method is not a constructor

var obj = {
  \*g() {},
};
new obj.g(); // TypeError: obj.g is not a constructor (changed in ES2016)
```

示例
--

### 简单示例


```js
var obj = {
  a: "foo",
  b() {
    return this.a;
  },
};
console.log(obj.b()); // "foo"
```

### 计算的属性名

该简写语法还支持计算的属性名称作为方法名。


```js
var bar = {
  foo0: function () {
    return 0;
  },
  foo1() {
    return 1;
  },
  ["foo" + 2]() {
    return 2;
  },
};

console.log(bar.foo0()); // 0
console.log(bar.foo1()); // 1
console.log(bar.foo2()); // 2
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-method-definitions |

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

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

参见
--

* `get`
* `set`
* Lexical grammar
剩余参数
====

**剩余参数**语法允许我们将一个不定数量的参数表示为一个数组。

尝试一下
----

语法
--


```js
function(a, b, ...theArgs) {
  // ...
}
```

描述
--

如果函数的最后一个命名参数以`...`为前缀，则它将成为一个由剩余参数组成的真数组，其中从`0`（包括）到`theArgs.length`（排除）的元素由传递给函数的实际参数提供。

在上面的例子中，`theArgs`将收集该函数的第三个参数（因为第一个参数被映射到`a`，而第二个参数映射到`b`）和所有后续参数。

### 剩余参数和 `arguments`对象的区别

剩余参数和 `arguments`对象之间的区别主要有三个：

* 剩余参数只包含那些没有对应形参的实参，而 `arguments` 对象包含了传给函数的所有实参。
* `arguments`对象不是一个真正的数组，而剩余参数是真正的 `Array`实例，也就是说你能够在它上面直接使用所有的数组方法，比如 `sort`，`map`，`forEach`或`pop`。
* `arguments`对象还有一些附加的属性（如`callee`属性）。
### 从 arguments 到数组

引入了剩余参数来减少由参数引起的样板代码。
```

// Before rest parameters, "arguments" could be converted to a normal array using:

function f(a, b) {

  var normalArray = Array.prototype.slice.call(arguments);
  // -- or --
  var normalArray = [].slice.call(arguments);
  // -- or --
  var normalArray = Array.from(arguments);

  var first = normalArray.shift(); // OK, gives the first argument
  var first = arguments.shift(); // ERROR (arguments is not a normal array)

}

// Now we can easily gain access to a normal array using a rest parameter

function f(...args) {
  var normalArray = args;
  var first = normalArray.shift(); // OK, gives the first argument
}
```

### 解构剩余参数

剩余参数可以被解构，这意味着他们的数据可以被解包到不同的变量中。请参阅解构赋值。


```js
function f(...[a, b, c]) {
  return a + b + c;
}

f(1); // NaN (b and c are undefined)
f(1, 2, 3); // 6
f(1, 2, 3, 4); // 6 (the fourth parameter is not destructured)
```

示例
--

因为`theArgs`是个数组，所以你可以使用`length`属性得到剩余参数的个数：


```js
function fun1(...theArgs) {
  alert(theArgs.length);
}

fun1(); // 弹出 "0", 因为 theArgs 没有元素
fun1(5); // 弹出 "1", 因为 theArgs 只有一个元素
fun1(5, 6, 7); // 弹出 "3", 因为 theArgs 有三个元素
```


下例中，剩余参数包含了从第二个到最后的所有实参，然后用第一个实参依次乘以它们：


```js
function multiply(multiplier, ...theArgs) {
  return theArgs.map(function (element) {
    return multiplier \* element;
  });
}

var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]
```


下例演示了你可以在剩余参数上使用任意的数组方法，而`arguments`对象不可以：


```js
function sortRestArgs(...theArgs) {
  var sortedArgs = theArgs.sort();
  return sortedArgs;
}

alert(sortRestArgs(5, 3, 7, 1)); // 弹出 1,3,5,7

function sortArguments() {
  var sortedArgs = arguments.sort();
  return sortedArgs; // 不会执行到这里
}

alert(sortArguments(5, 3, 7, 1)); // 抛出 TypeError 异常:arguments.sort is not a function
```


为了在`arguments`对象上使用`Array`方法，它必须首先被转换为一个真正的数组。


```js
function sortArguments() {
  var args = Array.prototype.slice.call(arguments);
  var sortedArgs = args.sort();
  return sortedArgs;
}
console.log(sortArguments(5, 3, 7, 1)); // shows 1, 3, 5, 7
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-function-definitions |

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

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

参见
--

* 函数指南
* 函数参考
* 展开语法（`...`）
* 默认参数
* `arguments`
* `Array`
setter
======

当尝试设置属性时，**`set`** 语法将对象属性绑定到要调用的函数。它还可以在类中应用。

尝试一下
----

语法
--


```js
{ set prop(val) { /\* … \*/ } }
{ set [expression](val) { /\* … \*/ } }
```

### 参数

`prop`

要绑定到给定函数的属性名。

`val`

用于保存尝试分配给`prop`的值的变量的一个别名。

表达式

从 ECMAScript 2015 开始，还可以使用一个计算属性名的表达式绑定到给定的函数。

描述
--

在 javascript 中，如果试着改变一个属性的值，那么对应的 setter 将被执行。setter 经常和 getter 连用以创建一个伪属性。不可能在具有真实值的属性上同时拥有一个 setter 器。

使用 set 语法时请注意：

* 它的标识符可以是数字或字符串；
* 它必须有一个明确的参数（详见 Incompatible ES5 change: literal getter and setter functions must now have exactly zero or one arguments）；
* 在对象字面量中，不能为一个已有真实值的变量使用 set，也不能为一个属性设置多个 set。
 ( `{ set x(v) { }, set x(v) { } }` 和 `{ x: ..., set x(v) { } }` 是不允许的 )
示例
--

### 在对象初始化时定义 setter

这将定义一个对象 `language` 的伪属性`current`，当`current`被分配一个值时，将使用该值更新`log`：


```js
const language = {
  set current(name) {
    this.log.push(name);
  },
  log: [],
};

language.current = "EN";
console.log(language.log); // ['EN']

language.current = "FA";
console.log(language.log); // ['EN', 'FA']
```


请注意，`current`属性是未定义的，访问它时将会返回 `undefined`。

### 用 `delete` 操作符移除一个 setter

我们可以使用`delete`操作符移除 setter。


```js
delete language.current;
```

### 使用 `defineProperty` 为当前对象定义 setter

我们可以随时使用 `Object.defineProperty()` 给一个已经存在的对象添加一个 setter。


```js
const o = { a: 0 };

Object.defineProperty(o, "b", {
  set: function (x) {
    this.a = x / 2;
  },
});

o.b = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
console.log(o.a); // 5
```

### 使用计算属性名


```js
const expr = "foo";

const obj = {
  baz: "bar",
  set [expr](v) {
    this.baz = v;
  },
};

console.log(obj.baz); // "bar"
obj.foo = "baz"; // run the setter
console.log(obj.baz); // "baz"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-method-definitions |

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

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

参见
--

* getter
* `delete`
* `Object.defineProperty()`
* `Object.prototype.__defineGetter__()`
* `Object.prototype.__defineSetter__()`
* JavaScript 指南中定义 Getter 和 Setter 一文
* 不兼容的 ES5 变化：字面量的 getter 和 setter 函数现在必须正好有零或一个参数
arguments[@@iterator]()
=======================

**`@@iterator`** 属性的初始值是和 `Array.prototype.values` 属性的初始值相同的对象。

语法
--
```

arguments[Symbol.iterator]()
```

示例
--

### 使用`for...of`循环的迭代


```js
function f() {
  // 你的浏览器必须支持 for..of 循环
  // 以及 for 循环中的 let 区域变量
  for (let letter of arguments) {
    console.log(letter);
  }
}
f("w", "y", "k", "o", "p");
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-createunmappedargumentsobject |
| ECMAScript Language Specification # sec-createmappedargumentsobject |

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

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

更多
--

* `Array.prototype.values()`
arguments.length
================

本次函数调用时传入函数的实参数量。

Syntax
------
```

arguments.length
```

描述
--

arguments.length 表示的是实际上向函数传入了多少个参数，这个数字可以比形参数量大，也可以比形参数量小 (形参数量的值可以通过Function.length获取到).

示例
--

### 示例：使用`arguments.length`

这个例中，我们定义了一个可以相加任意个数字的函数。


```js
function adder(base /\*, n2, ... \*/) {
  base = Number(base);
  for (var i = 0; i < arguments.length; i++) {
    base += Number(arguments[i]);
  }
  return base;
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-arguments-exotic-objects |

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

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

参见
--

* Function.length
按位或（|）
======

**按位或**（**`|`**）运算符在其中一个或两个操作数对应的二进制位为 `1` 时，该位的结果值为 `1`。

尝试一下
----

语法
--


```js
a | b
```

描述
--

操作数被转换为 32 位整数并由一系列二进制位（0 和 1）表示。超过 32 位的数字会丢弃其最高有效位。例如，以下超过 32 位的整数将被转换为 32 位整数：
```

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001
```


第一个操作数中的每个位都与第二个操作数中的相应位配对：*第一位*到*第一位*，*第二位*到*第二位*，依此类推。

运算符应用于每一对位，结果按位构造。

或运算的真值表为：

| a | b | a OR b |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
```

     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
```


将任何数字 `x` 与 `0` 进行按位或运算得到 `x`。

示例
--

### 使用按位或


```js
// 9 (00000000000000000000000000001001)
// 14 (00000000000000000000000000001110)

14 | 9;
// 15 (00000000000000000000000000001111)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # prod-BitwiseORExpression |

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

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

参见
--

* JS 指南中的位运算符
* 按位或赋值运算符
无符号右移（>>>）
==========

**无符号右移运算符（`>>>`）**（零填充右移）将左操作数计算为无符号数，并将该数字的二进制表示形式移位为右操作数指定的位数，取模 32。向右移动的多余位将被丢弃，零位从左移入。其符号位变为 `0`，因此结果始终为非负数。与其他按位运算符不同，零填充右移返回一个无符号 32 位整数。

尝试一下
----

语法
--


```js
a >>> b
```

描述
--

该运算符将第一个操作数向右移动指定的位数。向右移动的多余位将被丢弃。零位从左侧移入。其符号位变为 `0`，因此其表示的结果始终为非负数。与其他按位运算符不同，零填充右移返回无符号 32 位整数。

以十进制（以 10 为基数）数字 `9` 和 `-9` 的 32 位二进制表示为例：
```

     9 (base 10): 00000000000000000000000000001001 (base 2)
    -9 (base 10): 11111111111111111111111111110111 (base 2)
```


请注意，负十进制（以 10 为基数）数字 `-9` 的二进制表示形式是正十进制（以 10 为基数）数字 `9` 的二进制补码。也就是说，它是通过反转 `00000000000000000000000000001001` 的所有位并添加 `1` 来计算的。

在这两种情况下，二进制数的符号都由其最左边的位给出：对于正十进制数 `9`，二进制表示的最左边位是 `0`，对于负十进制数 `-9`，二进制表示的最左边位是 `1`。

对于正数 `9`，零填充右移和符号传播右移产生相同的结果：`9 >>> 2` 产生 `2`，与 `9 >> 2` 相同：
```

      9 (base 10): 00000000000000000000000000001001 (base 2)
                   --------------------------------
9 >>  2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
```


请注意，最右边的两个位 `01` 被移出，两个零从左边移入。

但是，请注意 `-9` 会发生什么情况：`-9 >> 2`（符号传播右移）产生 `-3`，但 `-9 >>> 2`（零填充右移）产生 1073741821：
```

      -9 (base 10): 11111111111111111111111111110111 (base 2)
                    --------------------------------
-9 >>  2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
```


请注意最右边的两个位 `11` 是如何移出的。对于 `-9 >> 2`（符号传播右移），最左边的 `1` 位的两个副本已从左侧移入，这保留了负号。另一方面，对于 `-9 >>> 2`（零填充右移），零从左移入，因此不会保留数字的负号，结果是一个（大）正数。

左操作数将被转换为无符号 32 位整数，这意味着浮点数将被截断，而超出 32 位边界的数字将溢出/下溢。

右操作数将转换为无符号的 32 位整数，然后取模 32，因此实际移位偏移量将始终是介于 0 和 31 之间的正整数（包括 0 和 31）。例如，`100 >>> 32` 与 `100 >>> 0` 相同（并产生 `100`），因为 32 模 32 是 0。

示例
--

### 使用无符号右移


```js
9 >>> 2; // 2
-9 >>> 2; // 1073741821
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-unsigned-right-shift-operator |

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

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

参见
--

* JS 指南：位运算符
* 无符号右移赋值运算符