ビット排他的論理和 (^) - JavaScript

ビット排他的論理和 (^)
=============

ビット排他的論理和演算子 (`^`) は、両方のオペランドの対応するビットの一方だけが `1` である位置のビットで `1` を返します。

試してみましょう
--------

構文
--

```js
a ^ b;
```

解説
--

オペランドは 32 ビットの整数値に変換され、ビット (ゼロまたは 1) の並びによって表現されます。32 ビットを超える数値は最上位のビットが破棄されます。例えば、次の 32 ビットを超える整数は 32 ビット整数に変換されます。
```

変換前: 11100110111110100000000000000110000000000001
変換後:             10100000000000000110000000000001
```

第 1 オペランドの各ビットは、第 2 オペランドの対応するビットと組みになります。*第 1 ビット*は*第 1 ビット*へ、*第 2 ビット*は*第 2 ビット*へ、という具合にです。

この演算子は各ビットの組み合わせに適用され、結果はビット単位で構築されます。

XOR 演算の真理値表は次のようになります。

| a | b | a XOR b |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
```

     9 (10 進数) = 00000000000000000000000000001001 (2 進数)
    14 (10 進数) = 00000000000000000000000000001110 (2 進数)
                   --------------------------------
14 ^ 9 (10 進数) = 00000000000000000000000000000111 (2 進数) = 7 (10 進数)
```

ある数 `x` と `0` のビット排他的論理和は `x` になります。

例
-

### ビット排他的論理和の使用

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

14 ^ 9;
// 7 (00000000000000000000000000000111)
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-BitwiseXORExpression |

ブラウザーの互換性
---------

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

関連情報
----

* ビット演算子 (JavaScript ガイド)
* ビット排他的論理和代入演算子


論理和 (

論理和 (||)
========

論理和 (`||`) 演算子 (論理的分割) をオペランドの組み合わせに対して使用すると、オペランドのうち 1 つ以上が true である場合に true になります。一般的には論理値（ブール値）で使用されます。その場合は論理値を返します。ただし `||` 演算子は実際には指定されたオペランドのうち一つの値を返すので、この演算子が論理値以外で使用された場合は、論理値以外の値を返すことになります。

試してみましょう
--------

構文
--

```js
expr1 || expr2;
```

解説
--

`expr1` が `true` に変換できる場合は `expr1` を返し、それ以外の場合は `expr2` を返します。

ある値が `true` に変換できる場合、その値は真値 (truthy) と呼ばれます。ある値が `false` に変換できる場合、その値は偽値 (falsy) と呼ばれます。

false に変換されうる式の例を示します。

* `null`
* `NaN`
* `0`
* 空文字列 (`""` または `''` または ````)
* `undefined`

`||` 演算子では論理値以外のオペランドを使用することができますが、返値が常に論理型プリミティブに変換することが可能であるため、論理演算子と見なすことができます。返値 (または一般的な式) を対応する論理値に明示的に変換するには、二重の否定演算子または `Boolean` コンストラクターを使用してください。

### 短絡評価

論理和の式は左から右へと評価され、下記の規則を使用して「短絡」評価が可能なように評価されます。

`(真値の式) || expr` は短絡評価で真値の式に評価されます。

短絡とは、上記の `expr` の部分が**評価されず**、したがって、これを行うことの副作用が効果を及ぼさないことを意味します（例えば、 `expr` が関数呼び出しであった場合、この場では呼び出されません）。これは、最初のオペランドが評価された時点で、すでに演算子の値が決定しているためです。例を示します。

```js
function A() {
  console.log("called A");
  return false;
}
function B() {
  console.log("called B");
  return true;
}

console.log(B() || A());
// 関数呼び出しによって "called B" がログ出力され、
// それから true (演算子の結果の値) が出力されます。
```

### 演算子の優先順位

以下の式は同じであるように見えるかもしれませんが、異なります。 `&&` 演算子は `||` 演算子よりも先に実行されるからです（演算子の優先順位を参照）。

```js
true || (false && false); // true を返す。 && が先に実行されるため
(true || false) && false; // false を返す。演算子の優先順位が適用されないため
```

例
-

### OR の使用

以下のコードは `||` (論理和) 演算子の例を示しています。

```js
o1 = true || true; // t || t は true を返す
o2 = false || true; // f || t は true を返す
o3 = true || false; // t || f は true を返す
o4 = false || 3 == 4; // f || f は false を返す
o5 = "Cat" || "Dog"; // t || t は "Cat" を返す
o6 = false || "Cat"; // f || t は "Cat" を返す
o7 = "Cat" || false; // t || f は "Cat" を返す
o8 = "" || false; // f || f は false を返す
o9 = false || ""; // f || f は "" を返す
o10 = false || varObject; // f || オブジェクトは varObject を返す
```

**メモ:** この演算子を使用していくつかの変数に既定値を提供する場合、*偽値*が使用されないことに注意してください。 `null` や `undefined` をフィルタリングする必要がある場合は、Null 合体演算子の使用を検討してください。

### 論理型の変換規則

#### AND から OR への変換

**論理型**に関する以下の操作は、

```js
bCondition1 && bCondition2;
```

常に以下のものと等しくなります。

```js
!(!bCondition1 || !bCondition2);
```

#### OR から AND への変換

**論理型**に関する以下の操作は、

```js
bCondition1 || bCondition2;
```

常に以下のものと等しくなります。

```js
!(!bCondition1 && !bCondition2);
```

### 入れ子になった括弧の除去

論理式は左から右に評価されるので、いくつかのルールに従って複雑な式から括弧を削除することは常に可能です。

**論理型**に関する以下の複合操作は、

```js
bCondition1 && (bCondition2 || bCondition3);
```

常に以下のものと等しくなります。

```js
!(!bCondition1 || (!bCondition2 && !bCondition3));
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-LogicalORExpression |

ブラウザーの互換性
---------

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

関連情報
----

* Null 合体演算子 (`??`)
* `Boolean`
* 真値
* 偽値


論理積 (&&) - JavaScript

論理積 (&&)
========

論理積 (`&&`) 演算子 (論理結合) を一組の論理型のオペランドに対して使用すると、すべてのオペランドが `true` である場合にのみ `true` になります。それ以外の場合は `false` になります。

一般的には、この演算子は左から右に向けて評価した際に最初の偽値のオペランドに遭遇したときにはその値を、またはすべてが真値であった場合は最後のオペランドの値を返します。

試してみましょう
--------

構文
--

```js
expr1 && expr2;
```

解説
--

論理積 (`&&`) はオペランドを左から右に向けて評価し、遭遇した最初の偽値のオペランドを直ちに返します。すべての値が真値であった場合、最後のオペランドの値が返されます。

ある値が `true` に変換できる場合、その値は真値 (truthy) と呼ばれます。ある値が `false` に変換できる場合、その値は偽値 (falsy) と呼ばれます。

false に変換することができる式の例を示します。

* `false`
* `null`
* `NaN`
* `0`
* 空文字列 (`""` または `''` または ````)
* `undefined`

論理積演算子は次のように、論理型でない値はそのまま温存して返します。

```js
result = "" && "foo"; // result には "" (空文字列) が代入される
result = 2 && 0; // result には 0 が代入される
result = "foo" && 4; // result には 4 が代入される
```

`&&` 演算子では論理値以外のオペランドを使用することができますが、返値が常に論理型プリミティブに変換することが可能であるため、論理演算子と見なすことができます。
 返値（または一般的な式）を対応する論理値に明示的に変換するには、二重の否定演算子または `Boolean` コンストラクターを使用してください。

### 短絡評価

 論理積の式は短絡演算子です。
 各オペランドが論理値に変換されるとき、ある変換結果が `false` であった場合、論理積演算子は停止してその偽値のオペランドの元の値を返します。残りのオペランドは評価**されません**。

以下の擬似コードを考えてみてください。
```

(偽値の式) && expr
```

`expr` の部分は**評価されません**。最初のオペランドである `(偽値の式)` が偽値と評価されるからです。
 `expr` が関数であった場合、その関数は呼び出されません。
 以下の例を参照してください。

```js
function A() {
  console.log("called A");
  return false;
}
function B() {
  console.log("called B");
  return true;
}

console.log(A() && B());
// 関数 A の呼び出しによって "called A" をログ出力し、
// && が false に評価され（関数 A が false を返し）、それから false をコンソールに出力します。
// 論理積演算子はここで短絡となり、関数 B は無視されます。
```

### 演算子の優先順位

AND 演算子は OR 演算子よりも高い優先順位を持つので、 `&&` 演算子は `||` 演算子よりも先に実行されます（演算子の優先順位を参照）。

```js
false || (true && true); // true を返す
true && (false || false); // false を返す
2 == 3 || (4 < 0 && 1 == 1); // false を返す
```

例
-

### 論理積の使用

以下のコードは `&&` (論理積) 演算子の例を示しています。

```js
a1 = true && true; // t && t は true を返す
a2 = true && false; // t && f は false を返す
a3 = false && true; // f && t は false を返す
a4 = false && 3 == 4; // f && f は false を返す
a5 = "Cat" && "Dog"; // t && t は "Dog" を返す
a6 = false && "Cat"; // f && t は false を返す
a7 = "Cat" && false; // t && f は false を返す
a8 = "" && false; // f && f は "" を返す
a9 = false && ""; // f && f は false を返す
```

### 論理型の変換規則

#### AND から OR への変換

**論理型**に関する以下の操作は、

```js
bCondition1 && bCondition2;
```

常に以下のものと等しくなります。

```js
!(!bCondition1 || !bCondition2);
```

#### OR から AND への変換

**論理型**に関する以下の操作は、

```js
bCondition1 || bCondition2;
```

常に以下のものと等しくなります。

```js
!(!bCondition1 && !bCondition2);
```

### 入れ子になった括弧の除去

論理式は左から右に評価されるので、いくつかのルールに従って複雑な式から括弧を削除することは常に可能です。

以下の**論理型**に関する複合操作は、

```js
bCondition1 || (bCondition2 && bCondition3);
```

常に以下のものと等しくなります。

```js
bCondition1 || (Condition2 && bCondition3;
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-LogicalANDExpression |

ブラウザーの互換性
---------

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

関連情報
----

* `Boolean`
* 真値
* 偽値


大なり (>) - JavaScript

大なり (>)
=======

大なり演算子 (`>`) は、左辺のオペランドが右辺のオペランドより大きい場合は `true` を返し、それ以外の場合は `false` を返します。

試してみましょう
--------

構文
--

```js
x > y;
```

解説
--

オペランドは、抽象関係比較アルゴリズムを使用して比較されます。このアルゴリズムの概要については、小なり演算子のドキュメントを参照して下さい。

例
-

### 文字列と文字列の比較

```js
console.log("a" > "b"); // false
console.log("a" > "a"); // false
console.log("a" > "3"); // true
```

### 文字列と数値の比較

```js
console.log("5" > 3); // true
console.log("3" > 3); // false
console.log("3" > 5); // false

console.log("hello" > 5); // false
console.log(5 > "hello"); // false

console.log("5" > 3n); // true
console.log("3" > 5n); // false
```

### 数値と数値の比較

```js
console.log(5 > 3); // true
console.log(3 > 3); // false
console.log(3 > 5); // false
```

### Number と BigInt の比較

```js
console.log(5n > 3); // true
console.log(3 > 5n); // false
```

### 論理値、null、undefined、NaN の比較

```js
console.log(true > false); // true
console.log(false > true); // false

console.log(true > 0); // true
console.log(true > 1); // false

console.log(null > 0); // false
console.log(1 > null); // true

console.log(undefined > 3); // false
console.log(3 > undefined); // false

console.log(3 > NaN); // false
console.log(NaN > 3); // false
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

ブラウザーの互換性
---------

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

関連情報
----

* 大なりイコール演算子
* 小なり演算子
* 小なりイコール演算子


符号なし右シフト (>>>) - JavaScript

符号なし右シフト (>>>)
==============

**符号なし右シフト演算子 (`>>>`)** (ゼロ埋め右シフト) は、1つ目のオペランドを指定されたビット数だけ右にずらします。右にずらしてあふれたビットは廃棄されます。0 のビットが左からずれて入ります。符号ビットは `0` になりますので、結果は負の数にはなりません。他のビット毎演算子とは異なり、ゼロ埋め右シフトは符号なし 32 ビット整数を返します。

試してみましょう
--------

構文
--

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

解説
--

この演算子は、1 つ目のオペランドを指定されたビット数だけ右にずらします。右にずらしてあふれたビットは廃棄されます。0 のビットが左からずれて入ります。符号ビットは `0` になりますので、結果は負の数にはなりません。他のビット毎演算子とは異なり、ゼロ埋め右シフトは符号なし 32 ビット整数を返します。

負の数ではない場合、ゼロ埋め右シフトと符号保存右シフトは同じ結果をになります。例えば、 `9 >>> 2` は 2 となり、 `9 >> 2` と同じになります。

```js
.     9 (10 進数): 00000000000000000000000000001001 (2 進数)
                   --------------------------------
9 >>> 2 (10 進数): 00000000000000000000000000000010 (2 進数) = 2 (10 進数)
```

しかし、これは負の数の場合は当てはまりません。例えば、 `-9 >>> 2` は 1073741821 になり、 `-9 >> 2` とは異なります (`-3` になる)。

```js
.     -9 (10 進数): 11111111111111111111111111110111 (2 進数)
                    --------------------------------
-9 >>> 2 (10 進数): 00111111111111111111111111111101 (2 進数) = 1073741821 (10 進数)
```

例
-

### 符号なし右シフトの使用

```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.

関連情報
----

* ビット演算子 (JavaScript ガイド)
* 符号なし右シフト代入演算子


super - JavaScript

super
=====

**super** キーワードは、オブジェクトの親の関数を呼び出すために使用できます。

`super.prop` および `super[expr]` 式は、class とオブジェクトリテラルの両方におけるあらゆるメソッド定義で有効です。

試してみましょう
--------

構文
--

```js
super([arguments]); // 親コンストラクターを呼び出します。
super.functionOnParent([arguments]);
```

解説
--

コンストラクターで使用する場合、`super` キーワードを単独で置き、`this` キーワードが使われる前に使用する必要があります。`super` キーワードは、親オブジェクトの関数を呼び出すためにも使用できます。

例
-

### クラス内での `super` の使用

このコードスニペットは、クラスの例 (ライブデモ) からとっています。`super()` を利用することで、`Rectangle` と `Square` のコンストラクターに共通する処理を重複して記述しないようにしています。

```js
class Rectangle {
  constructor(height, width) {
    this.name = "Rectangle";
    this.height = height;
    this.width = width;
  }
  sayName() {
    console.log("Hi, I am a ", this.name + ".");
  }
  get area() {
    return this.height \* this.width;
  }
  set area(value) {
    this._area = value;
  }
}

class Square extends Rectangle {
  constructor(length) {
    this.height; // ReferenceError になります。super を先に呼び出さなければなりません！

    // length の値で親クラスの constructor を呼びます。
    // Rectangle の width と height になります。
    super(length, length);

    // Note: 'this' を使う前に super() をコールしなければなりません。
    // でないと reference error になります。
    this.name = "Square";
  }
}
```

### 静的メソッドでの super の呼び出し

static メソッドでも super を呼び出すことができます。

```js
class Rectangle {
  static logNbSides() {
    return "I have 4 sides";
  }
}

class Square extends Rectangle {
  static logDescription() {
    return super.logNbSides() + " which are all equal";
  }
}
Square.logDescription(); // 'I have 4 sides which are all equal'
```

### super プロパティを削除するとエラーが発生する

親クラスのプロパティを削除するために、delete 演算子 や `super.prop`、`super[expr]` を使うことはできません。`ReferenceError` がスローされます。

```js
class Base {
  foo() {}
}
class Derived extends Base {
  delete() {
    delete super.foo; // this is bad
  }
}

new Derived().delete(); // ReferenceError: invalid delete involving 'super'.
```

### `super.prop` は書き込み不可能なプロパティを上書きできない

`Object.defineProperty` などで書き込み不可プロパティを定義した場合、`super` はプロパティの値を上書きできません。

```js
class X {
  constructor() {
    Object.defineProperty(this, "prop", {
      configurable: true,
      writable: false,
      value: 1,
    });
  }
}

class Y extends X {
  constructor() {
    super();
  }
  foo() {
    super.prop = 2; // 値を上書きできない
  }
}

var y = new Y();
y.foo(); // TypeError: "prop" は読み取り専用
console.log(y.prop); // 1
```

### オブジェクトリテラル内での `super.prop` の使用

super はオブジェクト初期化子 / リテラル記法内でも使用できます。この例では、 2 つのオブジェクトがメソッドを定義しています。 2 つ目のオブジェクトの中で、`super` が最初のオブジェクトのメソッドを呼び出しています。これは `Object.setPrototypeOf()` の助けで動作し、これは `obj2` のプロトタイプを `obj1` に設定するので、`super` は `method1` を `obj1` 上で見つけることができます。

```js
var obj1 = {
  method1() {
    console.log("method 1");
  },
};

var obj2 = {
  method2() {
    super.method1();
  },
};

Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // logs "method 1"
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-super-keyword |

ブラウザーの互換性
---------

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

関連情報
----

* クラス


new 演算子 - JavaScript

new 演算子
=======

**`new` 演算子**を使用すると、開発者はユーザー定義のオブジェクト型やコンストラクター関数を持つ組み込みオブジェクト型のインスタンスを作成することができます。

試してみましょう
--------

構文
--

```js
new constructor[([arguments])];
```

### 引数

`constructor`

オブジェクトインスタンスの型を指定するクラスまたは関数です。

`arguments`

`constructor` が呼び出される際の引数のリストです。

解説
--

**`new`** 演算子は次のことを行います。

1. 空のプレーンな JavaScript オブジェクトを生成します。
2. 新しいオブジェクトにプロパティ (`__proto__`) を追加し、コンストラクター関数のプロトタイプオブジェクトに結びつけます。

**メモ:** コンストラクター関数のプロトタイプに追加されたプロトタイプやオブジェクトは、そのためそのコンストラクター関数で（`new` を使用して）生成されたすべてのインスタンスからアクセスできます。
3. 新しく生成されたオブジェクトインスタンスを `this` コンテキストとして結びつけます。
 （すなわち、コンストラクター関数内の `this` へのすべての参照は、最初のステップで作成されたオブジェクトを参照するようになります。）
4. 関数がオブジェクトを返さない場合は `this` を返します。

ユーザー定義のオブジェクトを生成するには、2 つのステップが必要です。

1. オブジェクトの名前とプロパティを指定する関数を書くことで、オブジェクトの型を定義します。
 例えば、オブジェクト `Foo` を生成するコンストラクター関数は以下のようになります。

```js
function Foo(bar1, bar2) {
  this.bar1 = bar1;
  this.bar2 = bar2;
}
```

2. `new` 演算子を使用して、オブジェクトのインスタンスを生成します。

```js
var myFoo = new Foo("Bar 1", 2021);
```

**メモ:** オブジェクトは、別のオブジェクトそのものをプロパティとして持つことができます。後述の例をご覧ください。

コード `new Foo(...)` を実行すると、以下の処理が行われます。

1. `Foo.prototype` を継承する、新しいオブジェクトを生成します。
2. 指定した引数を伴ってコンストラクター関数 `Foo` が呼び出され、 `this` が新たに生成したオブジェクトに紐づけられます。`new Foo` は `new Foo()` と等価です。すなわち、引数を指定しない場合は `Foo` が引数なしで呼び出されます。
3. コンストラクター関数が返すオブジェクト (null, false, 3.1415 などのプリミティブ型ではないもの) が、 `new` 式の結果になります。コンストラクター関数が明示的にオブジェクトを返さない場合は、ステップ 1 で生成したオブジェクトを代わりに使用します（通常、コンストラクターは値を返しませんが、通常のオブジェクト生成プロセスをオーバーライドしたい場合はそのようにすることができます）。

以前生成したオブジェクトに、いつでもプロパティを追加できます。例えば `car1.color = "black"` という構文は、`color` プロパティを `car1` に追加して、値として "`black`" を代入します。

しかし、これは他のオブジェクトには影響を与えません。同じ型のすべてのオブジェクトに新たなプロパティを追加するには、 `Car` オブジェクト型の定義に対してプロパティを追加しなければなりません。

`Function.prototype` プロパティを使用して、以前定義したオブジェクトに対して共有のプロパティを追加できます。これはオブジェクト型のあるインスタンスのプロパティではなく、関数を使用して生成したすべてのオブジェクトで共有するプロパティを定義します。以下のコードでは `Car` 型のオブジェクトすべてに対して color プロパティを値 `"original color"` で定義しています。また、インスタンスオブジェクト `car1` の color プロパティに文字列の値 "`black`" を上書きしています。詳しくはプロトタイプをご覧ください。

```js
function Car() {}
car1 = new Car();
car2 = new Car();

console.log(car1.color); // undefined

Car.prototype.color = "original color";
console.log(car1.color); // 'original color'

car1.color = "black";
console.log(car1.color); // 'black'

console.log(Object.getPrototypeOf(car1).color); // 'original color'
console.log(Object.getPrototypeOf(car2).color); // 'original color'
console.log(car1.color); // 'black'
console.log(car2.color); // 'original color'
```

**メモ:** コンストラクター関数は通常の関数と同様に（つまり `new` 演算子なしで）呼び出すことができますが、この場合、新しいオブジェクトは作成されず、`this` の値も異なります。

例
-

### オブジェクトの型とオブジェクトのインスタンス

自動車用のオブジェクト型を作成したいとします。このオブジェクト型は `Car` という名前で、make、model、year というプロパティを持たせます。そのために、以下の関数を記述します。

```js
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
```

これで、以下のようにして `myCar` という名前のオブジェクトを生成できます。

```js
var myCar = new Car("Eagle", "Talon TSi", 1993);
```

この構文は `myCar` を生成して、プロパティに特定の値を代入しています。`myCar.make` の値は文字列 "Eagle"、`myCar.year` の値は整数 1993 などとなります。

`new` を呼び出して、`car` オブジェクトをいくつも生成できます。例えば、

```js
var kensCar = new Car("Nissan", "300ZX", 1992);
```

### それ自身が別のオブジェクトであるプロパティ

以下のように、`Person` という名前のオブジェクトを定義します。

```js
function Person(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}
```

そして、以下のように `Person` オブジェクトのインスタンスを新たに 2 つ生成します。

```js
var rand = new Person("Rand McNally", 33, "M");
var ken = new Person("Ken Jones", 39, "M");
```

さらに `Car` の定義を、以下のように `Person` オブジェクトを値としてとる `owner` プロパティを持つように書き換えます:

```js
function Car(make, model, year, owner) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.owner = owner;
}
```

新しいオブジェクトを生成するため、以下のように使用します。

```js
var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);
```

この構文では新しいオブジェクトを生成するときに文字列や整数のリテラル値を渡す代わりに、owner の引数としてオブジェクト `rand` や `ken` を渡しています。`car2` の所有者名を調べるには、以下のようにしてプロパティにアクセスできます。

```js
car2.owner.name;
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-new-operator |

ブラウザーの互換性
---------

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

関連情報
----

* `Function`
* `Reflect.construct()`
* `Object`


演算子の優先順位 - JavaScript

演算子の優先順位
========

**演算子の優先順位**は、演算子が互いにどのように解釈されるかを決定します。優先度の高い演算子は、優先度の低い演算子のオペランドになります。

試してみましょう
--------

優先度と結合性
-------

以下の表現で記述できる式を考えてみましょう。なお、`OP1` と `OP2` は演算子に置き換わります。

```js
a OP1 b OP2 c
```

`OP1` と `OP2` の優先順位（下記の一覧表を参照）が異なる場合は、優先順位の高い演算子が先に実行され、結合性は関係ありません。コードの中で加算が先に書かれているにもかかわらず、乗算の方が加算よりも優先順位が高く、先に実行されていることを確認してください。

```js
console.log(3 + 10 \* 2); // 23 を出力
console.log(3 + 10 \* 2); // 括弧の優先順位が高いので、23 を出力
console.log((3 + 10) \* 2); // 括弧が順位を変更するので 26 を出力
```

左結合（左から右）は `(a OP1 b) OP2 c` のように処理されることであり、右結合（右から左）は `a OP1 (b OP2 c)` のように解釈されることです。代入演算子は右結合なので、このように書くことができます。

```js
a = b = 5; // a = (b = 5); と書いたのと同じ
```

これで、`a` と `b` が 5 の値を得るという期待通りの結果を得ることができます。これは代入演算子が代入した値を返すためです。まず `b` に 5 が設定されます。そして `a` にも、代入演算子の右オペランドである `b = 5` が返す 5 が設定されるのです。

他の例として、べき乗演算子だけが右結合性を持ちますが、他の算術演算子は左結合性を持ちます。興味深いのは、結合性や優先順位に関係なく、評価の順序は常に左から右になることです。

|  |  |
| --- | --- |
| コード | 出力結果 |
|
```js
function echo(name, num) {
    console.log("Evaluating the " + name + " side");
    return num;
}
// 除算演算子 (/) の場合
console.log(echo("left", 6) / echo("right", 2));
```

 |
```
Evaluating the left side
Evaluating the right side
3
```

 |
|
```js
function echo(name, num) {
    console.log("Evaluating the " + name + " side");
    return num;
}
// べき乗演算子 (\*\*) の場合
console.log(echo("left", 2) \*\* echo("right", 3));
```

 |
```
Evaluating the left side
Evaluating the right side
8
```
 |

結合性の違いは、同じ優先順位の演算子が複数存在する場合に現れます。上の例のように演算子が一つだけの場合や、演算子の優先順位が異なる場合は、結合性は出力に影響を与えません。下の例では、同じ演算子が複数使われている場合に、結合性が出力結果にどのような影響を与えるかを見てみましょう。

|  |  |
| --- | --- |
| コード | 出力結果 |
|
```js
function echo(name, num) {
    console.log("Evaluating the " + name + " side");
    return num;
}
// 除算演算子 (/) の場合
console.log(echo("left", 6) / echo("middle", 2) / echo("right", 3));
```

 |
```
Evaluating the left side
Evaluating the middle side
Evaluating the right side
1
```

 |
|
```js
function echo(name, num) {
    console.log("Evaluating the " + name + " side");
    return num;
}
// べき乗演算子 (\*\*) の場合
console.log(echo("left", 2) \*\* echo("middle", 3) \*\* echo("right", 2));
```

 |
```
Evaluating the left side
Evaluating the middle side
Evaluating the right side
512
```

 |
|
```js
function echo(name, num) {
    console.log("Evaluating the " + name + " side");
    return num;
}
// 左と中央の間のべき乗を括弧で囲んだ場合
console.log((echo("left", 2) \*\* echo("middle", 3)) \*\* echo("right", 2));
```
 |
```
Evaluating the left side
Evaluating the middle side
Evaluating the right side
64
```
 |

上記のコードを見てください。`6 / 3 / 2` は、除算が左結合なので `(6 / 3) / 2` と同じになります。一方で、べき乗は右結合なので、`2 ** 3 ** 2` は `2 ** (3 ** 2)` と同じになります。したがって、 `(2 ** 3) ** 2` とすると上記の表にある通り、演算順序が変わって結果が 64 になります。

優先順位は結合度よりも優先されることを忘れないでください。そのため、割り算とべき乗を交ぜた場合、べき乗は割り算よりも先に計算されます。例えば `2 ** 3 / 3 ** 2` の結果は 0.8888888888888888 となります。これは `(2 ** 3) / (3 ** 2)` と同じだからです。

### グループ化と短絡評価の注意

下記の表では、**グループ化**が最上位の優先順位を持つものとして挙げられています。しかし、特に短絡が発生する場合は、グループ化記号 `( … )` の中の式が最初に評価されるとは限りません。

短絡評価は、条件付き評価を表す用語です。例えば、`a && (b + c)` という式において、`a` が偽値である場合、従属式である `(b + c)` は括弧で囲まれていても評価されません。この論理的分離演算子 ("OR") は「短絡的」といえるでしょう。論理的分離演算子の他にも、ほかに短絡が発生する演算子には、論理的結合 ("AND") 演算子、Null 合体演算子、オプション連鎖演算子、条件演算子があります。以下に例を示します。

```js
a || b \* c; // 最初に `a` を評価し、 `a` が「真値」であれば `a` を出力
a && b < c; // 最初に `a` を評価し、 `a` が「偽値」であれば `a` を出力
a ?? (b || c); // 最初に `a` を評価し、 `a` が `null` または `undefined` でなければ `a` を出力
a?.b.c; // 最初に `a` を評価し、 `a` が `null` または `undefined` であれば `undefined` を出力
```

例
-

```js
3 > 2 && 2 > 1;
// true を返す

3 > 2 > 1;
// 結果は false となる。3 > 2 は true であり、true は
// 不等号で 1 に変換されるため、true > 1 は 1 > 1 となり、
// false となる。(3 > 2) > 1 のように括弧を付けると明確になる。
```

一覧表
---

以下の表は優先順位の最も高いもの (19) から最も低いもの (1) の順に並べられています。

なお、スプレッド構文はこの表から除外しています。 — 理由は Stack Overflow の回答を引用します。「スプレッド構文は演算子ではなく、優先度はありません。これは配列リテラルと関数呼び出し（およびオブジェクトリテラル）の構文の一部です。」

| 優先順位 | 演算子の種類 | 結合性 | 演算子 |
| --- | --- | --- | --- |
| 19 | グループ化 | なし | `( … )` |
| 18 | メンバーへのアクセス | 左から右 | `… . …` |
| 計算値によるメンバーへのアクセス | 左から右 | `… [ … ]` |
| `new` (引数リスト付き) | なし | `new … ( … )` |
| 関数呼び出し | 左から右 | `… ( … )` |
| オプショナルチェーン | 左から右 | `?.` |
| 17 | `new` (引数リストなし) | 右から左 | `new …` |
| 16 | 後置インクリメント | なし | `… ++` |
| 後置デクリメント | `… --` |
| 15 | 論理 NOT (!) | 右から左 | `! …` |
| ビット単位 NOT (~) | `~ …` |
| 単項 + | `+ …` |
| 単項 - | `- …` |
| 前置インクリメント | `++ …` |
| 前置デクリメント | `-- …` |
| `typeof` | `typeof …` |
| `void` | `void …` |
| `delete` | `delete …` |
| `await` | `await …` |
| 14 | べき乗 (\*\*) | 右から左 | `… ** …` |
| 13 | 乗算 (\*) | 左から右 | `… * …` |
| 除算 (/) | `… / …` |
| 剰余 (%) | `… % …` |
| 12 | 加算 (+) | 左から右 | `… + …` |
| 減算(-) | `… - …` |
| 11 | 左ビットシフト (<<) | 左から右 | `… << …` |
| 右ビットシフト | `… >> …` |
| 符号なし右ビットシフト (>>>) | `… >>> …` |
| 10 | 小なり (<) | 左から右 | `… < …` |
| 小なりイコール (<=) | `… <= …` |
| 大なり (>) | `… > …` |
| 大なりイコール (>=) | `… >= …` |
| `in` | `… in …` |
| `instanceof` | `… instanceof …` |
| 9 | 等価 (==) | 左から右 | `… == …` |
| 不等価 (!=) | `… != …` |
| 厳密等価 (===) | `… === …` |
| 厳密不等価 (!==) | `… !== …` |
| 8 | ビット単位 AND (&) | 左から右 | `… & …` |
| 7 | ビット単位 XOR (^) | 左から右 | `… ^ …` |
| 6 | ビット単位 OR (|) | 左から右 | `… | …` |
| 5 | 論理 AND (&&) | 左から右 | `… && …` |
| 4 | 論理 OR (||) | 左から右 | `… || …` |
| Null 合体 (??) | 左から右 | `… ?? …` |
| 3 | 条件（三項）演算子 | 右から左 | `… ? … : …` |
| 2 | 代入 | 右から左 | `… = …` |
| `… += …` |
| `… -= …` |
| `… **= …` |
| `… *= …` |
| `… /= …` |
| `… %= …` |
| `… <<= …` |
| `… >>= …` |
| `… >>>= …` |
| `… &= …` |
| `… ^= …` |
| `… |= …` |
| `… &&= …` |
| `… ||= …` |
| `… ??= …` |
| `yield` | 右から左 | `yield …` |
| `yield*` | `yield* …` |
| 1 | カンマ / シーケンス | 左から右 | `… , …` |


ビット排他的論理和代入 (^=) - JavaScript

ビット排他的論理和代入 (^=)
================

ビット排他的論理和代入演算子 (`^=`) は、両方のオペランドの二進表現を使用し、それらに対してビット単位の XOR 演算を実行し、結果を変数に代入します。

試してみましょう
--------

構文
--

```js
x ^= y; // x = x ^ y
```

例
-

### ビット排他的論理和代入の使用

```js
let a = 5; // 00000000000000000000000000000101
a ^= 3; // 00000000000000000000000000000011

console.log(a); // 00000000000000000000000000000110
// 6

let b = 5; // 00000000000000000000000000000101
b ^= 0; // 00000000000000000000000000000000

console.log(b); // 00000000000000000000000000000101
// 5
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

ブラウザーの互換性
---------

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

関連情報
----

* JavaScript ガイドの代入演算子
* ビット排他的論理和演算子


べき乗 (**) - JavaScript

べき乗 (\*\*)
==========

べき乗演算子 (`**`) は、1 つ目のオペランドを2 つ目オペランドの累乗にした結果を返します。これは `Math.pow` と同等ですが、オペランドとして BigInt も受け入れます。

試してみましょう
--------

構文
--

```js
x \*\* y;
```

解説
--

べき乗演算子は右結合です。 `a ** b ** c` は `a ** (b ** c)` と等しくなります。

PHP や Python など、べき乗演算子 (`**`) を持つほとんどの言語では、べき乗演算子は単項演算子 (単項 `+` や単項 `-` など) よりも優先順位が高いと定義されていますが、いくつかの例外があります。例えば、Bash では `**` 演算子は単項演算子よりも優先順位が低いと定義されています。

JavaScript では、あいまいなべき乗式を記述することはできません。 つまり、基数の直前に単項演算子 (`+/-/~/!/delete/void/typeof`) を置くことはできません。 これを行うと、SyntaxError が発生します。

```js
-2 \*\* 2;
// Bashでは 4 他の言語では -4
// JavaScript では演算があいまいなため無効

-(2 \*\* 2);
// JavaScript では意図が明白なため -4
```

注意: 一部のプログラミング言語ではべき乗計算にキャレット記号 `^` を使用していますが、JavaScript ではビット排他的論理和にこの記号を使用しています。

例
-

### 基本的なべき乗

```js
2 \*\* 3; // 8
3 \*\* 2; // 9
3 \*\* 2.5; // 15.588457268119896
10 \*\* -1; // 0.1
NaN \*\* 2; // NaN
```

### 結合性

```js
2 \*\* 3 \*\* 2; // 512
2 \*\* (3 \*\* 2); // 512
(2 \*\* 3) \*\* 2; // 64
```

### 単項演算子との使用

べき乗式の結果の符号を反転させる例です。

```js
-(2 \*\* 2); // -4
```

べき乗式の基底を強制的に負の数にする例です。

```js
(-2) \*\* 2; // 4
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-exp-operator |

ブラウザーの互換性
---------

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

関連情報
----

* 加算演算子
* 減算演算子
* 除算演算子
* 乗算演算子
* 剰余演算子
* インクリメント演算子
* デクリメント演算子
* 単項マイナス演算子
* 単項プラス演算子


剰余代入 (%=) - JavaScript

剰余代入 (%=)
=========

剰余代入演算子 (`%=`) は、変数を右辺のオペランドの値で除算し、剰余を変数に代入します。

試してみましょう
--------

構文
--

```js
x %= y; // x = x % y
```

例
-

### 剰余代入の使用

```js
// 以下の変数を想定
// bar = 5

bar %= 2; // 1
bar %= "foo"; // NaN
bar %= 0; // NaN
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

ブラウザーの互換性
---------

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

関連情報
----

* JavaScript ガイドの代入演算子
* 剰余演算子


小なりイコール (<=) - JavaScript

小なりイコール (<=)
============

小なりイコール演算子 (`<=`) は、左のオペランドが右のオペランドより小さいか等しい場合に `true` を返し、それ以外の場合は `false` を返します。

試してみましょう
--------

構文
--

```js
x <= y;
```

解説
--

オペランドは、抽象関係比較アルゴリズムを使用して比較されます。 このアルゴリズムの概要については、小なり演算子のドキュメントを参照して下さい。

例
-

### 文字列と文字列の比較

```js
console.log("a" <= "b"); // true
console.log("a" <= "a"); // true
console.log("a" <= "3"); // false
```

### 文字列と数値の比較

```js
console.log("5" <= 3); // false
console.log("3" <= 3); // true
console.log("3" <= 5); // true

console.log("hello" <= 5); // false
console.log(5 <= "hello"); // false
```

### 数値と数値の比較

```js
console.log(5 <= 3); // false
console.log(3 <= 3); // true
console.log(3 <= 5); // true
```

### Number と BigInt の比較

```js
console.log(5n <= 3); // false
console.log(3 <= 3n); // true
console.log(3 <= 5n); // true
```

### 論理値、null、undefined、NaN の比較

```js
console.log(true <= false); // false
console.log(true <= true); // true
console.log(false <= true); // true

console.log(true <= 0); // false
console.log(true <= 1); // true

console.log(null <= 0); // true
console.log(1 <= null); // false

console.log(undefined <= 3); // false
console.log(3 <= undefined); // false

console.log(3 <= NaN); // false
console.log(NaN <= 3); // false
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

ブラウザーの互換性
---------

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

関連情報
----

* 大なり演算子
* 大なりイコール演算子
* 小なり演算子


void 演算子 - JavaScript

void 演算子
========

**`void` 演算子**は与えられた式 (`expression`) を評価し、`undefined` を返します。

試してみましょう
--------

構文
--

```js
void expression;
```

解説
--

この演算子により、何らかの値を生成する評価式を、式が `undefined` と評価されることが望ましい場面に置くことができます。

`void` 演算子は、よく単にプリミティブ値 `undefined` を得る目的で使われ、一般的に "`void(0)`" と書かれます（これは "`void 0`" と等価です）。この目的であれば、グローバル変数 `undefined` を使用することができます。

なお、`void` 演算子の 優先順位 を考慮するべきであり、括弧は `void` 演算子に続く式の解決を明確にするのに役立つとされています。

```js
void 2 == "2"; // (void 2) == '2', false を返す
void (2 == "2"); // void (2 == '2'), undefined を返す
```

例
-

### 即時実行関数式

即時実行関数式 を使用する場合、 `void` により `function` キーワードが宣言ではなく式として扱うよう強制することができます。

```js
void (function iife() {
  console.log("Executed!");
})();

// Output: "Executed!"
```

上記の関数を `void` キーワードなしで実行すると、**捕捉されない SyntaxError** が発生します。

### JavaScript URI

`javascript:` の URI に対応しているブラウザーでは、 URI の中のコードを評価し、返値が `undefined` でない限り、返された値でページの内容を置き換えます。 `void` 演算子は、`undefined` を返すために使用できます。

```html
<a href="javascript:void(0);"> Click here to do nothing </a>

<a href="javascript:void(document.body.style.backgroundColor='green');">
  Click here for green background
</a>
```

**メモ:** `javascript:` 擬似プロトコルは控えめなイベントハンドラーなどの代替であり、積極的に使用するべきではないでしょう。

### アロー関数からのリーク防止

 アロー関数は略式の中括弧のない構文を導入しており、式を返します。
 これは、以前は何も返さなかった関数呼び出しの結果を返すことで、意図しない副作用を引き起こす可能性があります。関数の返値が使用されないことを想定している場合は、安全のため void 演算子に渡すことで、（例えば） API の変更によってアロー関数の動作が変更されないようにすることができます。

```js
button.onclick = () => void doSomething();
```

これにより、 `doSomething` の返値が `undefined` から `true` に変わっても、このコードの動作が変わらないことが保証されます。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-void-operator |

ブラウザーの互換性
---------

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

関連情報
----

* `undefined`


関数式 - JavaScript

関数式
===

**`function`** キーワードは、式の中で関数を定義するために使用されます。

`function` 関数宣言やアロー構文を用いて関数を定義することもできます。

試してみましょう
--------

構文
--

```js
function (param0) {
  statements
}
function (param0, param1) {
  statements
}
function (param0, param1, /\* …, \*/ paramN) {
  statements
}

function name(param0) {
  statements
}
function name(param0, param1) {
  statements
}
function name(param0, param1, /\* …, \*/ paramN) {
  statements
}
```

**メモ:** 式文はキーワード `function` から始めることができません。 `function` 宣言との曖昧さをさけるためです。 `function` キーワードは文を受け入れることができない文脈で現れた時だけ式を開始します。

### 引数

`name` 省略可

関数名。省略可能で、その場合は関数は*無名*になります。 name は関数本体のみのローカルです。

`paramN` 省略可

関数の正式な引数の名前。引数の構文については、関数リファレンスを参照してください。

`statements` 省略可

関数の本体を構成する文です。

解説
--

`function` 式は `function` 宣言とよく似ており、ほとんど同じ書式ですあります。 `function` 式と `function` 宣言の主な相違点は、*関数名*です。 `function` 式では、*無名*関数を生成するために、関数名を省略できます。 `function` 式は、定義するとすぐに実行する IIFE （即時実行関数）として使用できます。詳細については、関数の章を参照してください。

### 関数式の巻き上げ

JavaScript の関数式は、関数宣言と違って巻き上げられません。定義前に関数式を使用することはできません。

```js
console.log(notHoisted); // undefined
// 変数名は巻き上げが行われますが、定義は行われません。
// そのため undefined になります。
notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function () {
  console.log("bar");
};
```

### 名前付き関数式

関数内でその関数自身を参照する必要がある場合は、名前付き関数式を作成する必要があります。この名前は関数本体（スコープ）に対してローカルです。これにより、再帰呼び出しを行う場合に非推奨の `arguments.callee` プロパティを使用せずに済みます。

```js
const math = {
  factit: function factorial(n) {
    console.log(n);
    if (n <= 1) {
      return 1;
    }
    return n \* factorial(n - 1);
  },
};

math.factit(3); //3;2;1;
```

関数式に名前が付けられている場合、関数の `name` プロパティには、構文から推測される暗黙の名前 (関数が割り当てられている変数など) ではなく、その名前が設定されます。

宣言とは異なり、関数式の名前は読み取り専用です。

```js
function foo() {
  foo = 1;
}
foo();
console.log(foo); // 1
(function foo() {
  foo = 1; // TypeError: Assignment to constant variable.
})();
```

例
-

### 無名関数の作成

次の例では、無名関数を定義してそれを `x` に割り当てます。 関数は引数の 2 乗を返します。

```js
const x = function (y) {
  return y \* y;
};
```

### 関数をコールバックとして使用

コールバックとしてより頻繁に使われます。

```js
button.addEventListener("click", function (event) {
  console.log("button is clicked!");
});
```

### 即時実行関数式 (IIFE) の使用

無名の関数が生成され、呼び出されます。

```js
(function () {
  console.log("Code runs!");
})();

// または

!function () {
  console.log("Code runs!");
}();
```

仕様書
---

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

ブラウザーの互換性
---------

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

関連情報
----

* 関数ガイド
* 関数
* `function`
* `Function`
* アロー関数


論理和代入 (

論理和代入 (||=)
===========

論理和代入演算子 (`x ||= y`) は、`x` が偽値である場合にのみ代入を行います。

試してみましょう
--------

構文
--

```js
expr1 ||= expr2;
```

解説
--

### 短絡評価 (ショートサーキット)

論理和演算子は次のように動作します。

```js
x || y;
// x が真値の場合 x を返します
// x が真値ではない場合 y を返します
```

論理和演算子は、1 つ目のオペランドがまだ結果を決定していない場合にのみ、2 つ目のオペランドの評価を行う短絡評価をします。

論理和代入も同様に短絡評価され、右辺の評価が行われる論理演算の場合にのみ代入が行われます。言い替えれば、`x ||= y` は以下と等価です。

```js
x || (x = y);
```

そして、常に代入が行われる以下と等価ではありません。

```js
x = x || y;
```

なお、この動作は、数学的な代入演算子やビット代入演算子とは異なることに注意してください。

例
-

### 既定の内容を設定する

"lyrics" 要素が空の場合は、既定値を表示します。

```js
document.getElementById("lyrics").textContent ||= "No lyrics.";
```

ここでの短絡評価は、要素が不必要に更新されることがなく、追加のパースやレンダリング作業、フォーカスの損失などの望ましくない副作用を引き起こすことがないので、特に有益です。

注意: チェック対象の API が返す値に注意してください。空の文字列 (偽値) が返される場合は、`||=` を使用する必要があります。それ以外の場合 (返値が `null` または `undefined` の場合) は `??=` 演算子を使用してください。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

ブラウザーの互換性
---------

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

関連情報
----

* 論理和演算子 (||)
* Null 合体演算子 (`??`)
* ビット論理和代入演算子 (`|=`)
* 真値
* 偽値


条件 (三項) 演算子 - JavaScript

条件 (三項) 演算子
===========

**条件 (三項) 演算子**は JavaScript では唯一の、3 つのオペランドをとる演算子です。条件に続いて疑問符 (`?`)、そして条件が真値であった場合に実行する式、コロン (`:`) が続き、条件が偽値であった場合に実行する式が最後に来ます。この演算子は、 `if` 文の代替としてよく用いられます。

試してみましょう
--------

構文
--

```js
condition ? exprIfTrue : exprIfFalse;
```

### 引数

`condition`

値が条件として使用される式です。

`exprIfTrue`

`condition` が真値 (`true` と等しいか、 `true` に変換できる値) と評価された場合に評価される式です。

`exprIfFalse`

`condition` が偽値 (`false` と等しいか、 `false` に変換できる値) と評価された場合に評価される式です。

解説
--

`false` についていえば、偽値になる可能性がある式は `null`, `NaN`, `0`, 空文字列 (`""`), `undefined` です。 `condition` がこのうちの何れかであれば、条件演算子の結果は `exprIfFalse` の式を実行した結果になります。

例
-

### 単純な例

```js
var age = 26;
var beverage = age >= 21 ? "ビール" : "ジュース";
console.log(beverage); // "ビール"
```

### null 値の扱い

よくある使い方の一つに、 `null` になる可能性がある値を扱うというものがあります。

```js
let greeting = (person) => {
  let name = person ? person.name : `お客さん`;
  return `やあ、${name}`;
};

console.log(greeting({ name: `アリス` })); // "やあ、アリス"
console.log(greeting(null)); // "やあ、お客さん"
```

### 条件の連鎖

三項演算子は右結合で、すなわち以下のような方法で `if … else if … else if … else` の連鎖と同様に「連鎖」させることができます。

```js
function example(…) {
    return condition1 ? value1
         : condition2 ? value2
         : condition3 ? value3
         : value4;
}

// 以下のものと同等です。

function example(…) {
    if (condition1) { return value1; }
    else if (condition2) { return value2; }
    else if (condition3) { return value3; }
    else { return value4; }
}
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-conditional-operator |

ブラウザーの互換性
---------

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

関連情報
----

* if 文
* Null 合体演算子
* オプション連鎖
* コードでの意思決定 — 条件文
* 式と演算子


インクリメント (++) - JavaScript

インクリメント (++)
============

インクリメント演算子 (`++`) は、オペランドをインクリメント (1 を加算) して値を返します。

試してみましょう
--------

構文
--

```js
x++;
++x;
```

解説
--

オペランドに後置で演算子を付けると (例えば、 `x++`) 、インクリメント演算子はインクリメントしますが、インクリメント前の値を返します。

オペランドに前置で演算子を付けると (例えば、 `++x`) 、インクリメント演算子はインクリメントし、インクリメント後の値を返します。

例
-

### 後置インクリメント

```js
let x = 3;
y = x++;

// y = 3
// x = 4
```

### 前置インクリメント

```js
let a = 2;
b = ++a;

// a = 3
// b = 3
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-postfix-increment-operator |

ブラウザーの互換性
---------

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

関連情報
----

* 加算演算子
* 減算演算子
* 除算演算子
* 乗算演算子
* 剰余演算子
* べき乗演算子
* デクリメント演算子
* 単項マイナス演算子
* 単項プラス演算子


デクリメント (--) - JavaScript

デクリメント (--)
===========

デクリメント演算子 (`--`) は、オペランドをデクリメント (1 を減算) して値を返します。

試してみましょう
--------

構文
--

```js
x--;
--x;
```

解説
--

オペランドに後置で演算子を付けると (例えば `x--`)、デクリメント演算子はデクリメントしますが、デクリメント前の値を返します。

オペランドに前置で演算子を付けると (例えば `--x`)、デクリメント演算子はデクリメントし、デクリメント後の値を返します。

例
-

### 後置デクリメント

```js
let x = 3;
y = x--;

// y = 3
// x = 2
```

### 前置デクリメント

```js
let a = 2;
b = --a;

// a = 1
// b = 1
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-postfix-decrement-operator |

ブラウザーの互換性
---------

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

関連情報
----

* 加算演算子
* 減算演算子
* 除算演算子
* 乗算演算子
* 剰余演算子
* べき乗演算子
* インクリメント演算子
* 単項マイナス演算子
* 単項プラス演算子


オプショナルチェーン (?.) - JavaScript

オプショナルチェーン (?.)
===============

**オプショナルチェーン** (optional chaining) 演算子 (**`?.`**) は、接続されたオブジェクトチェーンの深くに位置するプロパティの値を、チェーン内の各参照が正しいかどうかを明示的に確認せずに読み込むことを可能にします。

`?.` 演算子の機能は `.` チェーン演算子と似ていますが、参照が nullish (`null` または `undefined`) の場合にエラーとなるのではなく、式が短絡され `undefined` が返されるところが異なります。関数呼び出しで使用すると、与えられた関数が存在しない場合、 `undefined` を返します。

これは、参照が失われた可能性のある連結されたプロパティにアクセスする時、結果的に短く単純な式になります。また、必要なプロパティの存在が保証されていない場合にオブジェクトのコンテンツを探索するのにも役立ちます。

オプショナルチェーンは、宣言されていないルートオブジェクトでは使用できませんが、未定義のルートオブジェクトで使用できます。

試してみましょう
--------

構文
--

```js
obj.val?.prop;
obj.val?.[expr];
obj.arr?.[index];
obj.func?.(args);
```

解説
--

オプショナルチェーン演算子は、参照や関数が `undefined` または `null` である可能性がある場合でも、接続されたオブジェクトの値に簡単にアクセスする手段を提供します。

たとえば、入れ子構造を持つオブジェクト `obj` を考えましょう。オプショナルチェーン演算子なしで深い入れ子になったサブプロパティにアクセスするには、次のように、各プロパティ間の参照を確認する必要があります。

```js
let nestedProp = obj.first && obj.first.second;
```

`obj.first.second` の値にアクセスする前に、 `obj.first` の値が `null` または `undefined` でないことを確認します。これにより、 `obj.first` をテストせず `obj.first.second` にアクセスしたときに起きるエラーを防ぐことができます。

しかし、オプショナルチェーン演算子 (`?.`) を使えば、`obj.first.second` にアクセスしようとする前に `obj.first` の状態を明示的にテストする必要がなくなります。

```js
let nestedProp = obj.first?.second;
```

`?.` を `.` の代わりに用いることで、 JavaScript が `obj.first.second` にアクセスしようとする前に `obj.first` が `null` または `undefined` でないことを暗黙的に確かめるようになります。`obj.first` が `null` または `undefined` であった場合、式が自動的に短絡され、 `undefined` が返ります。

これは、一時的な変数が作成されないことを除き、次の式と等価です。

```js
let temp = obj.first;
let nestedProp = temp === null || temp === undefined ? undefined : temp.second;
```

### 関数呼び出しにおけるオプショナルチェーン演算子

存在しない可能性がある関数の呼び出しを試行するときに、オプショナルチェーンを使うことができます。これはたとえば、ユーザーの端末上で使えなかったり、実装が古かったりするために使えなかったりする可能性がある API を使うときに役立ちます。

関数呼び出しでオプショナルチェーン演算子を用いた場合、メソッドが見つからないときは自動的に `undefined` が返り、例外は発生しません。

```js
let result = someInterface.customMethod?.();
```

**メモ:** 関数ではない名前のプロパティがあった場合、 `?.` を使用すると `TypeError` 例外が発生します
 (`someInterface.customMethod is not a function`)。

**メモ:** `someInterface` 自体が `null` または `undefined` である場合にも、 `TypeError` 例外が発生します (`someInterface is null`)。 `someInterface` 自体が `null` または `undefined` である可能性がある場合は、この位置にも `?.` を使用して `someInterface?.customMethod?.()` のようにする必要があります。

#### 省略可能なコールバックやイベントハンドラーの扱い

コールバックを使う場合や、オブジェクトからメソッドを分割代入を利用して取り出す場合に、存在しない値がある可能性があり、その存在を検証するまで関数として呼び出せません。その場合 `?.` を利用することで、検証の必要性を回避できます。

```js
// Written as of ES2019
function doSomething(onContent, onError) {
  try {
    // ... do something with the data
  } catch (err) {
    if (onError) {
      // Testing if onError really exists
      onError(err.message);
    }
  }
}
```

```js
// Using optional chaining with function calls
function doSomething(onContent, onError) {
  try {
    // ... do something with the data
  } catch (err) {
    onError?.(err.message); // no exception if onError is undefined
  }
}
```

### オプショナルチェーン演算子と式の組み合わせ

プロパティアクセサーのブラケット表記法を使用している式のプロパティにアクセスする際にも、オプショナルチェーン演算子を使用することができます。

```js
let nestedProp = obj?.["prop" + "Name"];
```

### オプショナルチェーン演算子は代入の左辺値では使用できない

```js
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
```

### オプショナルチェーンによる配列要素へのアクセス

```js
let arrayItem = arr?.[42];
```

例
-

### 基本的な例

次の例では、マップに存在しない `bar` メンバの `name` プロパティを取得しようとしています。したがって、結果は `undefined` になります。

```js
let myMap = new Map();
myMap.set("foo", { name: "baz", desc: "inga" });

let nameBar = myMap.get("bar")?.name;
```

### 短絡評価

式と一緒にオプショナルチェーン演算子を用いたとき、左側のオペランドが `null` または `undefined` である場合、その式は評価されなくなります。

```js
let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];

console.log(x); // 0 となる。 x は加算されていない
```

### オプショナルチェーンをつなげて使う

入れ子になったオブジェクトでは、オプショナルチェーン演算子を何度でも使うことができます。

```js
let customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls", // 詳細な住所は不明
  },
};
let customerCity = customer.details?.address?.city;

// … これはオプショナルチェーンの関数呼び出しでも動作します
let customerName = customer.name?.getName?.(); // メソッドが存在しないので、 customerName は undefined
```

### Null 合体演算子と共に使う

Null 合体演算子はオプショナルチェーンの後につけることで、値が存在しなかったときの既定値を指定することができます。

```js
let customer = {
  name: "Carl",
  details: { age: 82 },
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-OptionalExpression |

ブラウザーの互換性
---------

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

関連情報
----

* Null 合体演算子


大なりイコール (>=) - JavaScript

大なりイコール (>=)
============

大なりイコール演算子 (`>=`) は、左辺のオペランドが右辺のオペランド以上の場合は `true` を返し、それ以外の場合は `false` を返します。

試してみましょう
--------

構文
--

```js
x >= y;
```

解説
--

オペランドは、抽象関係比較アルゴリズムを使用して比較されます。 このアルゴリズムの概要については、小なり演算子のドキュメントを参照して下さい。

例
-

### 文字列と文字列の比較

```js
console.log("a" >= "b"); // false
console.log("a" >= "a"); // true
console.log("a" >= "3"); // true
```

### 文字列と数値の比較

```js
console.log("5" >= 3); // true
console.log("3" >= 3); // true
console.log("3" >= 5); // false

console.log("hello" >= 5); // false
console.log(5 >= "hello"); // false
```

### 数値と数値の比較

```js
console.log(5 >= 3); // true
console.log(3 >= 3); // true
console.log(3 >= 5); // false
```

### Number と BigInt の比較

```js
console.log(5n >= 3); // true
console.log(3 >= 3n); // true
console.log(3 >= 5n); // false
```

### 論理値、null、undefined、NaN の比較

```js
console.log(true >= false); // true
console.log(true >= true); // true
console.log(false >= true); // false

console.log(true >= 0); // true
console.log(true >= 1); // true

console.log(null >= 0); // true
console.log(1 >= null); // true

console.log(undefined >= 3); // false
console.log(3 >= undefined); // false

console.log(3 >= NaN); // false
console.log(NaN >= 3); // false
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

ブラウザーの互換性
---------

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

関連情報
----

* 大なり演算子
* 小なり演算子
* 小なりイコール演算子


スプレッド構文 - JavaScript

スプレッド構文
=======

**スプレッド構文** (`...`) を使うと、配列式や文字列などの反復可能オブジェクトを、0 個以上の引数 (関数呼び出しの場合) や要素 (配列リテラルの場合) を期待された場所で展開したり、オブジェクト式を、0 個以上のキーと値の組 (オブジェクトリテラルの場合) を期待された場所で展開したりすることができます。

試してみましょう
--------

解説
--

スプレッド構文は、オブジェクトや配列のすべての要素を何らかのリストに入れる必要がある場合に使用することができます。

上記の例では、定義された関数は、引数として `x`、`y`、`z` を受け取り、これらの値の合計を返します。配列の値も定義されています。

この関数を呼び出す際には、スプレッド構文と配列名 — `...numbers` を使って、配列内のすべての値を渡します。

配列に 3 つ以上の数値が含まれていた場合 (`[1, 2, 3, 4]` など)、4 つすべてが渡されることを除けば、それでも問題なく動作しますが、次のように関数にさらに引数を追加しない限り、最初の 3 つだけが使用されます。

```js
function sum(x, y, z, n) {
  return x + y + z + n;
}
```

上記の例はやや柔軟性に欠けます。スプレッド構文の真価は、オブジェクトや配列などに含まれる要素の数に関係なく、同じ値で動作することにあります。

一般的には、ローカルデータストアに新しいアイテムを追加したり、保存されているすべてのアイテムに新しく追加されたアイテムを加えて表示したりする場合に使用されます。この種の操作を非常にシンプルに表すと、次のようになります。

```js
let numberStore = [0, 1, 2];
let newNumber = 12;
numberStore = [...numberStore, newNumber];
```

上記の例では、最後の行を何度でも再実行して、配列の最後に 12 を追加し続けることができます。

構文
--

関数呼び出しの場合:

```js
myFunction(...iterableObj); // iterableObj のすべての要素を関数 myFunction の引数として渡す
```

配列リテラルや文字列の場合:

```js
[...iterableObj, "4", "five", 6]; // iterableObj のすべての要素を挿入することで、2 つの配列を組み合わせる
```

オブジェクトリテラルの場合 (ECMAScript 2018 の新機能)

```js
let objClone = { ...obj }; // オブジェクトのすべてのキーと値の組を渡す
```

残余構文 (引数)
---------

残余構文はスプレッド構文と外見がよく似ていますが、こちらはスプレッド構文とは逆の働きといえます。スプレッド構文が要素を展開するのに対して、残余構文は複数の要素を集約して 1 つのオブジェクトに「濃縮」します。残余引数を参照してください。

例
-

### 関数呼び出しでの展開

#### apply() を置き換える

配列の要素を引数にして関数を呼び出すには `Function.prototype.apply()` を使うのが一般的です。

```js
function myFunction(x, y, z) {}
let args = [0, 1, 2];
myFunction.apply(null, args);
```

スプレッド構文を使うと、上のコードは次のように書くことができます。

```js
function myFunction(x, y, z) {}
let args = [0, 1, 2];
myFunction(...args);
```

スプレッド構文は、引数リストのどの引数でも使用でき、またスプレッド構文は複数回使用することもできます。

```js
function myFunction(v, w, x, y, z) {}
let args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
```

#### new 演算子の適用

`new` によってコンストラクターを呼び出すとき、配列と `apply()` を**直接**使用することはできません (`apply()` は `[[Call]]` を実行するのであり `[[Construct]]` ではない)。ただし、配列はスプレッド構文のおかげで簡単に `new` を使用することができます。

```js
let dateFields = [1970, 0, 1]; // 1 Jan 1970
let d = new Date(...dateFields);
```

スプレッド構文を使わずに同じ結果を得るには、専用の関数を使う**間接的**な手段を取らざるをえません。

```js
function applyAndNew(constructor, args) {
  function partial() {
    return constructor.apply(this, args);
  }
  if (typeof constructor.prototype === "object") {
    partial.prototype = Object.create(constructor.prototype);
  }
  return partial;
}

function myConstructor() {
  console.log("arguments.length: " + arguments.length);
  console.log(arguments);
  this.prop1 = "val1";
  this.prop2 = "val2";
}

let myArguments = ["hi", "how", "are", "you", "mr", null];
let myConstructorWithArguments = applyAndNew(myConstructor, myArguments);

console.log(new myConstructorWithArguments());
// (internal log of myConstructor): arguments.length: 6
// (internal log of myConstructor): ["hi", "how", "are", "you", "mr", null]
// (log of "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}
```

### 配列リテラルでのスプレッド構文

#### より強力な配列リテラル

スプレッド構文を使用しない場合、既存の配列を一部として使用して新しい配列を作成するには、配列リテラル構文は十分ではなく、`push()`, `splice()`, `concat()` などを組み合わせて使う高圧的なコードを使用しなければなりません。

```js
let parts = ["shoulders", "knees"];
let lyrics = ["head", ...parts, "and", "toes"];
// ["head", "shoulders", "knees", "and", "toes"]
```

関数の引数と同様に、`...` は配列リテラルのどこでも、何回でも使えます。

#### 配列を複製する

```js
let arr = [1, 2, 3];
let arr2 = [...arr]; // arr.slice() のような動きです

arr2.push(4);
// arr2 は [1, 2, 3, 4] になります
// arr は変更されません
```

**メモ:** コピーは 1 段階の深さで行われます。そのため、次の例のような多次元配列のようなオブジェクトをコピーする場合には適さないでしょう。(`Object.assign()` についても同じことが言えます。)

```js
let a = [[1], [2], [3]];
let b = [...a];

b.shift().shift();
// 1

// しまった。 'a' も影響を受けてしまった。
a;
// [[], [2], [3]]
```

#### 配列を連結するより良い方法

ある配列を既存の配列の末尾に連結するには、`Array.prototype.concat()` がよく使われます。スプレッド構文を使用しないと、これは次のように行われます。

```js
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];

// arr2 のすべての要素を arr1 に追加する
arr1 = arr1.concat(arr2);
```

スプレッド構文を使うと、次のように書けます。

```js
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];

arr1 = [...arr1, ...arr2];
// arr1 は [0, 1, 2, 3, 4, 5] となる
// 注: これ以外に const を使用すると、TypeError (invalid assignment) が発生します
```

`Array.prototype.unshift()` は、値の配列を既存の配列の先頭に挿入するためによく使われます。スプレッド構文を使用しないと、これは次のように行われます。

```js
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];

// arr2 のすべての要素を arr1 へ移植します
Array.prototype.unshift.apply(arr1, arr2);

// arr1 is now [3, 4, 5, 0, 1, 2]</pre>
```

スプレッド構文を使うと、次のようになります。

```js
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];

arr1 = [...arr2, ...arr1];
// arr1 is now [3, 4, 5, 0, 1, 2]
```

**メモ:** `unshift()` とは異なり、これは新しい `arr1` を生成しており、その場では元の `arr1` を変更しません。

### オブジェクトリテラルでのスプレッド構文

Rest/Spread Properties for ECMAScript proposal (ES2018) では、`オブジェクトリテラル`でのスプレッド構文が追加されています。スプレッド構文の対象となるオブジェクトの列挙可能なプロパティを、新しいオブジェクトにコピーします。

浅いコピー (プロトタイプを除く) の作成や、マージしたオブジェクトの作成が `Object.assign()` を使うよりも短いコードで書けます。

```js
let obj1 = { foo: "bar", x: 42 };
let obj2 = { foo: "baz", y: 13 };

let clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

let mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }
```

`Object.assign()` は`セッター`を起動しますが、スプレッド構文は起動しないことに注意してください。

スプレッド構文は `Object.assign()` 関数を置き換えたり模倣することはできないことに注意してください。

```js
let obj1 = { foo: "bar", x: 42 };
let obj2 = { foo: "baz", y: 13 };
const merge = (...objects) => ({ ...objects });

let mergedObj1 = merge(obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }

let mergedObj2 = merge({}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
```

上記の例では、スプレッド構文は期待通りに動作しません。残りの引数があるため、引数の*配列*がオブジェクトリテラルにとして展開されます。

### 反復可能オブジェクトにのみ利用可能

オブジェクト自体は反復可能ではありませんが、配列の中で使用したり、`map()`, `reduce()`, `assign()` などの反復関数と共に使用したりすることで反復可能になります。2 つのオブジェクトをスプレッド演算子で結合する場合は、結合時に別の反復処理関数を使用することを前提としています。

スプレッド構文 (スプレッドプロパティの場合を除く) は、反復可能オブジェクトにのみ適用できます。

```js
let obj = { key1: "value1" };
let array = [...obj]; // TypeError: obj is not iterable
```

### 大量の値を展開する場合

JavaScript エンジンには、引数の個数に上限があります。関数呼び出しでのスプレッド構文では、引数の個数がその上限を超えてしまう可能性に留意してください。詳細は `apply()` のページを参照してください。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-SpreadElement |
| ECMAScript Language Specification # prod-ArgumentList |
| ECMAScript Language Specification # prod-PropertyDefinition |

ブラウザーの互換性
---------

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

関連情報
----

* 残余引数 (こちらも '`...`')
* `Function.prototype.apply()` (こちらも '`...`')


厳密不等価 (!==) - JavaScript

厳密不等価 (!==)
===========

厳密不等価演算子 (`!==`) は、2 つのオペランドが等しくないことを検査し、論理値で結果を返します。不等価演算子とは異なり、厳密不等価演算子はオペランドの型が異なる場合、常に異なると判断します。

試してみましょう
--------

構文
--

```js
x !== y;
```

解説
--

厳密不等価演算子は、オペランドが等しくないことを検査します。これは厳密等価演算子の逆に当たるので、以下の 2 行は常に同じ結果になります。

```js
x !== y;

!(x === y);
```

比較アルゴリズムの詳細については、厳密等価演算子のページを参照して下さい。

厳密等価演算子と同様に、厳密不等価演算子はオペランドの型が異なると、常に異なるものと見なします。

```js
3 !== "3"; // true
```

例
-

### オペランドが同じ型である場合の比較

```js
console.log("hello" !== "hello"); // false
console.log("hello" !== "hola"); // true

console.log(3 !== 3); // false
console.log(3 !== 4); // true

console.log(true !== true); // false
console.log(true !== false); // true

console.log(null !== null); // false
```

### オペランドが異なる型である場合の比較

```js
console.log("3" !== 3); // true

console.log(true !== 1); // true

console.log(null !== undefined); // true
```

### オブジェクトの比較

```js
const object1 = {
  name: "hello",
};

const object2 = {
  name: "hello",
};

console.log(object1 !== object2); // true
console.log(object1 !== object1); // false
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-equality-operators |

ブラウザーの互換性
---------

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

関連情報
----

* 等価演算子
* 不等価演算子
* 厳密等価演算子


乗算代入 (*=) - JavaScript

乗算代入 (\*=)
==========

乗算代入演算子 (`*=`) は、変数に右のオペランドの値を乗算し、結果を変数に代入します。

試してみましょう
--------

構文
--

```js
x \*= y; // x = x \* y
```

例
-

### 乗算代入の使用

```js
// 次の変数を想定
// bar = 5

bar \*= 2; // 10
bar \*= "foo"; // NaN
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

ブラウザーの互換性
---------

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

関連情報
----

* JavaScript ガイドの代入演算子
* 乗算演算子


async function* 式 - JavaScript

async function\* 式
==================

**`async function*`** キーワードは、式の内部で非同期ジェネレーター関数を定義するために使用できます。

また、 `async function*` 宣言 を使って非同期ジェネレーター関数を定義することもできます。

試してみましょう
--------

構文
--

```js
async function\* (param0) {
  statements
}
async function\* (param0, param1) {
  statements
}
async function\* (param0, param1, /\* …, \*/ paramN) {
  statements
}

async function\* name(param0) {
  statements
}
async function\* name(param0, param1) {
  statements
}
async function\* name(param0, param1, /\* …, \*/ paramN) {
  statements
}
```

**メモ:** 式文 は、 `async function*` 宣言との曖昧さを避けるために、キーワード `async function` で始めることはできません。 `async function` キーワードは、文を受け付けないコンテキストに現れたときのみ、式を開始します。

### 引数

`name` 省略可

関数名。省略可能で、その場合関数は無名となります。この名前は関数本体に対してのみローカルです。

`paramN` 省略可

関数の正式な引数の名前です。引数の構文については、関数リファレンスを参照してください。

`statements` 省略可

関数本体を構成する文です。

解説
--

`async function*` 式は `async function*` 宣言 ととても似ており、ほとんど同じ構文を持っています。 `async function*` 式と `async function*` 宣言の主な違いは関数名で、 `async function*` 式では無名関数を作成するために省略することができます。 `async function*` 式は定義されるとすぐに実行される IIFE (Immediately Invoked Function Expression) として使うことができ、アドホックな非同期反復可能オブジェクトを作成することができます。詳しくは関数の章も参照してください。

例
-

### async function\* の使用

次の例では、無名の非同期ジェネレーター関数を定義し、それを `x` に代入しています。この関数は引数の2乗を返します。

```js
const x = async function\* (y) {
  yield Promise.resolve(y \* y);
};
x(6)
  .next()
  .then((res) => console.log(res.value)); // 36
```

仕様書
---

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

ブラウザーの互換性
---------

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

関連情報
----

* `async function*`
* `AsyncGeneratorFunction`
* 反復処理プロトコル
* `yield`
* `yield*`
* Functions


厳密等価 (===) - JavaScript

厳密等価 (===)
==========

厳密等価演算子 (`===`) は、二つのオペランドが等しいことを検査し、論理値で結果を返します。等価演算子とは異なり、厳密等価演算子はオペランドの型が異なる場合、常に異なるものと判断します。

試してみましょう
--------

構文
--

```js
x === y;
```

解説
--

厳密等価演算子 (`===` および `!==`) は、厳密等価比較アルゴリズムを使用して 2 つのオペランドを比較します。

* オペランドの型が異なる場合は、 `false` を返します。
* 両方のオペランドがオブジェクトである場合、同じオブジェクトを指している場合に限り `true` を返します。
* 両方のオペランドが `null` または両方のオペランドが `undefined` であった場合は `true` を返します。
* どちらかのオペランドが `NaN` であった場合は `false` を返します。
* それ以外の場合は、2 つのオペランドの値を比較します。
    + 数値型は同じ値の数値である必要があります。 `+0` と `-0` は同じ値と見なされます。
    + 文字列型は同じ文字が同じ順序で並んでいる必要があります。
    + 論理型は両方が `true` であるか両方が `false` である必要があります。

この演算子と等価 (`==`) 演算子の最も顕著な違いは、オペランドの型が異なる場合、 `==` 演算子は比較前に同じ型に変換しようとすることです。

例
-

### オペランドが同じ型である場合の比較

```js
console.log("hello" === "hello"); // true
console.log("hello" === "hola"); // false

console.log(3 === 3); // true
console.log(3 === 4); // false

console.log(true === true); // true
console.log(true === false); // false

console.log(null === null); // true
```

### オペランドが異なる型である場合の比較

```js
console.log("3" === 3); // false

console.log(true === 1); // false

console.log(null === undefined); // false
```

### オブジェクトの比較

```js
const object1 = {
  name: "hello",
};

const object2 = {
  name: "hello",
};

console.log(object1 === object2); // false
console.log(object1 === object1); // true
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-equality-operators |

ブラウザーの互換性
---------

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

関連情報
----

* 等価演算子
* 不等価演算子
* 厳密不等価演算子


除算 (/) - JavaScript

除算 (/)
======

除算演算子 (`/`) は、左のオペランドを被除数とし、右のオペランドを除数としたオペランド同士の除算結果を生成します。

試してみましょう
--------

構文
--

```js
x / y;
```

例
-

### 基本的な除算

```js
1 / 2; // 0.5

Math.floor(3 / 2); // 1

1.0 / 2.0; // 0.5
```

### ゼロ除算

```js
2.0 / 0; // Infinity

2.0 / 0.0; // Infinity。 0.0 === 0 であるため

2.0 / -0.0; // -Infinity
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-multiplicative-operators |

ブラウザーの互換性
---------

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

関連情報
----

* 加算演算子
* 減算演算子
* 乗算演算子
* 剰余演算子
* べき乗演算子
* インクリメント演算子
* デクリメント演算子
* 単項マイナス演算子
* 単項プラス演算子


yield* - JavaScript

yield\*
=======

**`yield*` 式**は別のジェネレーターや反復可能なオブジェクトに委任するために使用されます。

試してみましょう
--------

構文
--

```js
yield\* expression;
```

`expression`

反復可能なオブジェクトを返す式。

解説
--

`yield*` 式はオペランドを反復し、それによって返されたそれぞれの値をもたらします。

`yield*` 式自体の値は、イテレーターが閉じたとき（つまり `done` が `true` のとき）に返される値です。

例
-

### 別のジェネレータに委任する

次のコードでは、 `g1()` によってもたらされる値は、 `g2()` で得られているものと同じように `next()` の呼び出しから返されます。

```js
function\* g1() {
  yield 2;
  yield 3;
  yield 4;
}

function\* g2() {
  yield 1;
  yield\* g1();
  yield 5;
}

const iterator = g2();

console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: 4, done: false}
console.log(iterator.next()); // {value: 5, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
```

### 他の反復可能なオブジェクト

ジェネレータオブジェクトのほかに、 `yield*` は他の種類の反復 (例えば、配列、文字列、 `arguments` オブジェクト) を `yield` することができます。

```js
function\* g3() {
  yield\* [1, 2];
  yield\* "34";
  yield\* Array.from(arguments);
}

const iterator = g3(5, 6);

console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: "3", done: false}
console.log(iterator.next()); // {value: "4", done: false}
console.log(iterator.next()); // {value: 5, done: false}
console.log(iterator.next()); // {value: 6, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
```

### `yield*` 式自体の値

`yield*` は式であり、文ではありません。そのため、値に評価されます。

```js
function\* g4() {
  yield\* [1, 2, 3];
  return "foo";
}

function\* g5() {
  const g4ReturnValue = yield\* g4();
  console.log(g4ReturnValue); // 'foo'
  return g4ReturnValue;
}

const iterator = g5();

console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false} done is false because g5 generator isn't finished, only g4
console.log(iterator.next()); // {value: 'foo', done: true}
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator-function-definitions-runtime-semantics-evaluation |

ブラウザーの互換性
---------

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

関連情報
----

* Iterator プロトコル (en-US)
* `function*`
* `function* expression`
* `yield`


分割代入 - JavaScript

分割代入
====

**分割代入** (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。

試してみましょう
--------

構文
--

```js
const [a, b] = array;
const [a, , b] = array;
const [a = aDefault, b] = array;
const [a, b, ...rest] = array;
const [a, , b, ...rest] = array;
const [a, b, ...{ pop, push }] = array;
const [a, b, ...[c, d]] = array;

const { a, b } = obj;
const { a: a1, b: b1 } = obj;
const { a: a1 = aDefault, b = bDefault } = obj;
const { a, b, ...rest } = obj;
const { a: a1, b: b1, ...rest } = obj;
const { [key]: a } = obj;

let a, b, a1, b1, c, d, rest, pop, push;
[a, b] = array;
[a, , b] = array;
[a = aDefault, b] = array;
[a, b, ...rest] = array;
[a, , b, ...rest] = array;
[a, b, ...{ pop, push }] = array;
[a, b, ...[c, d]] = array;

({ a, b } = obj); // 中括弧が必要
({ a: a1, b: b1 } = obj);
({ a: a1 = aDefault, b = bDefault } = obj);
({ a, b, ...rest } = obj);
({ a: a1, b: b1, ...rest } = obj);
```

解説
--

オブジェクトリテラルと配列リテラルは、いくつかのデータを*アドホック*にまとめる簡単な方法を提供します。

```js
const x = [1, 2, 3, 4, 5];
```

分割代入は似たような構文を使用しますが、代入の左辺が元の変数からどの値を受け取るかを定義します。

```js
const x = [1, 2, 3, 4, 5];
const [y, z] = x;
console.log(y); // 1
console.log(z); // 2
```

同様に、オブジェクトを代入の左辺で分割することができます。

```js
const obj = { a: 1, b: 2 };
const { a, b } = obj;
// これは以下のものと同様です
// const a = obj.a;
// const b = obj.b;
```

この機能は、Perl や Python などの言語に存在する機能に似ています。

### バインドと代入

オブジェクトと配列の分割代入には、2 種類の分割代入のパターンがあります。**バインドパターン**と**代入パターン**であり、構文が若干異なります。

バインドパターンでは、宣言キーワード (`var`、`let`、`const`) から始めます。次に、個々のプロパティを変数にバインドするか、さらに構造化する必要があります。

```js
const obj = { a: 1, b: { c: 2 } };
const {
  a,
  b: { c: d },
} = obj;
// `a` と `d` の 2 つの変数はバインドされます。
```

すべての変数で同じ宣言を共有するので、ある変数だけ再代入可能にし、他は読み取り専用にしたい場合は、`let` で 1 回、`const` で 1 回の 2 回の分割代入が必要になる場合があります。

```js
const obj = { a: 1, b: { c: 2 } };
const { a } = obj; // a は定数
let {
  b: { c: d },
} = obj; // d は再代入可能
```

代入パターンでは、パターンはキーワードで始まりません。それぞれの分解されたプロパティが、代入先に代入されます。この代入先は `var` や `let` であらかじめ宣言されているか、他のオブジェクトのプロパティです。一般的には、代入式の左辺に現れることができるものなら何でも構いません。

```js
const numbers = [];
const obj = { a: 1, b: 2 };
({ a: numbers[0], b: numbers[1] } = obj);
// `a` および `b` プロパティが `numbers` へ代入される
```

**メモ:** 宣言なしでオブジェクトリテラルの分割代入を使用する場合、代入文を囲む括弧 `( ... )` が必要です。

`{ a, b } = { a: 1, b: 2 }` は、左辺の `{a, b}` がオブジェクトリテラルではなくブロックとみなされるため、単体では有効な構文ではありません。しかし、`({ a, b } = { a: 1, b: 2 })` は有効であり、`const { a, b } = { a: 1, b: 2 }` も同様です。

もし、お使いのコーディングスタイルで末尾のセミコロンを記述していない場合は、`( ... )` 式の前にセミコロンを記述する必要がありますし、前の行の関数を実行するために使用される可能性もあります。

上のコードの等価な *バインドパターン* は、有効な構文ではないことに注意してください。

```js
const numbers = [];
const obj = { a: 1, b: 2 };
const { a: numbers[0], b: numbers[1] } = obj;

// これは次のものと等価です。
// const numbers[0] = obj.a;
// const numbers[1] = obj.b;
// これは完全に正しくありません。
```

### 既定値

それぞれの分解されたプロパティは、*既定値* を持つことができます。既定値は、プロパティが存在しないか、値が `undefined` である場合に使用されます。プロパティが値 `null` を持つ場合は使用されません。

```js
const [a = 1] = []; // a is 1
const { b = 2 } = { b: undefined }; // b is 2
const { c = 2 } = { c: null }; // c is null
```

既定値には、任意の式を指定することができます。必要なときだけ評価されます。

```js
const { b = console.log("hey") } = { b: 2 };
// `b` が定義されており、既定値を評価する必要がないため、何らかのログを出力することはありません。
```

### 残余プロパティ

分解パターンの終わりには、残余プロパティ `...rest` を指定することができます。このパターンは、オブジェクトや配列の残りのプロパティをすべて新しいオブジェクトや配列に格納します。

```js
const { a, ...others } = { a: 1, b: 2, c: 3 };
console.log(others); // { b: 2, c: 3 }

const [first, ...others2] = [1, 2, 3];
console.log(others2); // [2, 3]
```

残余プロパティは、パターンの最後のものでなければならず、末尾のカンマがあってはなりません。

```js
const [a, ...b,] = [1, 2, 3];

// SyntaxError: rest element may not have a trailing comma
// 常に最後の要素として残余演算子を使用することを考慮してください。
```

### 他の構文での分解パターン

言語が変数をバインドしてくれる多くの構文では、同様に分解パターンを使用することができます。これには、次のようなものがあります。

* `for...in` および `for...of` ループのループ変数
* 関数の引数
* `catch` のバインド変数

配列やオブジェクトの分解に固有の機能については、下記の個別の例を参照してください。

例
-

### 配列の分割代入

#### 簡単な例

```js
const foo = ["one", "two", "three"];

const [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"
```

#### 代入元より多い要素を持つ分割代入

代入の右辺に指定された長さ *N* の配列からの配列分割では、代入の左辺に指定された変数の数が *N* より大きい場合、最初の *N* 個の変数にのみ値が割り当てられます。残りの変数の値は undefined となります。

```js
const foo = ["one", "two"];

const [red, yellow, green, blue] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // undefined
console.log(blue); // undefined
```

#### 変数の入れ替え

分割代入を使用して、複数の変数の値を入れ替えることができます。

分割代入を使用せずに 2 つの値を交換するには、一時変数（または、一部の低水準言語においては XOR 交換アルゴリズム）が必要です。

```js
let a = 1;
let b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

const arr = [1, 2, 3];
[arr[2], arr[1]] = [arr[1], arr[2]];
console.log(arr); // [1, 3, 2]
```

#### 関数から返された配列の解析

関数は配列を返すことがあります。分割代入によって、返された配列の使用をより簡潔に記述できます。

この例では、`f()` は出力として値 `[1, 2]` を返しており、分割代入により 1 行で解析できます。

```js
function f() {
  return [1, 2];
}

const [a, b] = f();
console.log(a); // 1
console.log(b); // 2
```

#### 返値の無視

関心のない返値は無視することができます。

```js
function f() {
  return [1, 2, 3];
}

const [a, , b] = f();
console.log(a); // 1
console.log(b); // 3

const [c] = f();
console.log(c); // 1
```

このようにすべての返値を無視することもできます。

```js
[, ,] = f();
```

#### 残余プロパティとしてのバインドパターンの使用

配列の分割代入の残余プロパティは、別の配列やオブジェクトの結合パターンにすることができます。これにより、配列のプロパティとインデックスを同時に展開することができます。

```js
const [a, b, ...{ pop, push }] = [1, 2];
console.log(a, b); // 1 2
console.log(pop, push); // [Function pop] [Function push]
```

```js
deconst [a, b, ...[c, d]] = [1, 2, 3, 4];
console.log(a, b, c, d); // 1 2 3 4
```

これらのバインドパターンは、それぞれの残余プロパティがリストの最後のものである限り、入れ子にすることも可能です。

```js
const [a, b, ...[c, d, ...[e, f]]] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c, d, e, f); // 1 2 3 4 5 6
```

一方、オブジェクトの分解では、残余プロパティとして識別子しか保有することができません。

```js
const { a, ...{ b } } = { a: 1, b: 2 };
// SyntaxError: `...` must be followed by an identifier in declaration contexts

let a, b;
({ a, ...{ b } } = { a: 1, b: 2 });
// SyntaxError: `...` must be followed by an assignable reference in assignment contexts
```

#### 正規表現に一致するものからの値の展開

正規表現オブジェクトの `exec()` メソッドは一致するものを見つけ、最初に一致した文字列全体の一部と、正規表現内の各括弧で囲まれたグループに一致した文字列の部分を含む配列を返します。分割代入によって、簡単にこの配列の一部分を取り出せます。また必要でない場合は、完全一致を無視できます。

```js
function parseProtocol(url) {
  const parsedURL = /^(\w+):\/\/([^/]+)\/(.\*)$/.exec(url);
  if (!parsedURL) {
    return false;
  }
  console.log(parsedURL);
  // ["https://developer.mozilla.org/ja/docs/Web/JavaScript",
  // "https", "developer.mozilla.org", "ja/docs/Web/JavaScript"]

  const [, protocol, fullhost, fullpath] = parsedURL;
  return protocol;
}

console.log(
  parseProtocol("https://developer.mozilla.org/ja/docs/Web/JavaScript"),
);
// "https"
```

#### 任意のイテレーターで配列の分割代入の使用

配列の分解を行うと、右辺の反復可能プロトコルが呼び出されます。したがって、配列に限らず、任意の反復可能オブジェクトを分割代入することができます。

```js
const [a, b] = new Map([
  [1, 2],
  [3, 4],
]);
console.log(a, b); // [1, 2] [3, 4]
```

反復可能でないものは、配列として分解できません。

```js
const obj = { 0: "a", 1: "b", length: 2 };
const [a, b] = obj;
// TypeError: obj is not iterable
```

反復可能オブジェクトは、すべてのバインドが代入されるまでしか反復処理しません。

```js
const obj = {
  \*[Symbol.iterator]() {
    for (const v of [0, 1, 2, 3]) {
      console.log(v);
      yield v;
    }
  },
};
const [a, b] = obj; // 0 と 1 のみ出力
```

残りのバインドは貪欲に評価され、古い反復可能オブジェクトを使用する代わりに、新しい配列を作成します。

```js
const obj = {
  \*[Symbol.iterator]() {
    for (const v of [0, 1, 2, 3]) {
      console.log(v);
      yield v;
    }
  },
};
const [a, b, ...rest] = obj; // Logs 0 1 2 3
console.log(rest); // [2, 3] （配列）
```

### オブジェクトの分割代入

#### 基本的な例

```js
const user = {
  id: 42,
  isVerified: true,
};

const { id, isVerified } = user;

console.log(id); // 42
console.log(isVerified); // true
```

#### 新しい変数名への代入

オブジェクトから変数を取り出して、オブジェクトのプロパティとは異なる名前の変数に代入することができます。

```js
const o = { p: 42, q: true };
const { p: foo, q: bar } = o;

console.log(foo); // 42
console.log(bar); // true
```

ここで、例えば、`const {p: foo} = o` はオブジェクト `o` から `p` という名前のプロパティを取り、`foo` という名前のローカル変数へ代入します。

#### 新しい変数名の割り当てと既定値の提供

プロパティは、次のようにすることができます。

* オブジェクトから取り出して異なる名前の変数に代入します。
* 取り出した値が `undefined` である場合に備えて、既定値を割り当てます。

```js
const { a: aa = 10, b: bb = 5 } = { a: 3 };

console.log(aa); // 3
console.log(bb); // 5
```

#### 関数の引数として渡されたオブジェクトからのプロパティの展開

 関数の引数に渡されたオブジェクトは、変数に展開し、関数本体内でアクセスすることも可能です。
 オブジェクトの代入に関しては、分割構文により、新しい変数に元のプロパティと同じ名前または異なる名前を持たせることができ、元のオブジェクトがプロパティを定義していない場合の既定値を割り当てることができます。

ユーザーに関する情報を格納したオブジェクトを考えてみましょう。

```js
const user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
    firstName: "Jane",
    lastName: "Doe",
  },
};
```

 ここでは、合格したオブジェクトのプロパティを同じ名前の変数に展開する方法を示します。
 引数値 `{ id }` は、関数に渡されたオブジェクトの `id` プロパティを同じ名前の変数に展開し、関数内で使用できるようにすることを示します。

```js
function userId({ id }) {
  return id;
}

console.log(userId(user)); // 42
```

 展開した変数の名前を定義することができます。
 ここでは、`displayName` というプロパティを展開し、関数本体内で使用するために `dname` という名前に変更しています。

```js
function userDisplayName({ displayName: dname }) {
  return dname;
}

console.log(userDisplayName(user)); // `jdoe`
```

 入れ子になっているオブジェクトも展開することができます。
 下記の例では、プロパティ `fullname.firstName` が `name` という変数に展開されています。

```js
function whois({ displayName, fullName: { firstName: name } }) {
  return `${displayName} is ${name}`;
}

console.log(whois(user)); // "jdoe is Jane"
```

#### 関数の引数に対する既定値の設定

既定値は `=` で指定することができ、指定したプロパティが渡されたオブジェクトに存在しない場合、変数の値として使用されます。

既定値が、サイズが `'big'` で、座標が `x: 0, y: 0` で、半径が 25 の関数です。

```js
function drawChart({
  size = "big",
  coords = { x: 0, y: 0 },
  radius = 25,
} = {}) {
  console.log(size, coords, radius);
  // グラフの描画
}

drawChart({
  coords: { x: 18, y: 30 },
  radius: 30,
});
```

上記の `drawChart` の関数呼び出し形式では、次のようにして、分割代入の左辺に、右辺側で空のオブジェクトリテラルを代入しています。

右辺の代入がない関数を書くこともできます。しかし、右辺の代入を取り除いた場合、関数は実行されたときに少なくともひとつの引数が提供されることを期待しますが、この形式では何も引数を指定せずに単純に `drawChart()` を呼び出すことができます。この設計は引数を指定せずに関数を呼び出せるようにしたい場合に役に立ちますし、もう一方の形式は、オブジェクトを確実に関数に渡したい場合に役に立ちます。

詳しくは、デフォルト引数 > 既定値のある分割代入の引数を参照してください。

### 入れ子になったオブジェクトと配列の分割代入

```js
const metadata = {
  title: "Scratchpad",
  translations: [
    {
      locale: "de",
      localizationTags: [],
      lastEdit: "2014-04-14T08:43:37",
      url: "/de/docs/Tools/Scratchpad",
      title: "JavaScript-Umgebung",
    },
  ],
  url: "/ja/docs/Tools/Scratchpad",
};

const {
  title: englishTitle, // rename
  translations: [
    {
      title: localeTitle, // rename
    },
  ],
} = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"
```

#### イテレーターでの分割代入の利用

```js
const people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith",
    },
    age: 35,
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones",
    },
    age: 25,
  },
];

for (const {
  name: n,
  family: { father: f },
} of people) {
  console.log(`Name: ${n}, Father: ${f}`);
}

// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"
```

#### 計算されたオブジェクトのプロパティの名前と分割代入

オブジェクトリテラルのような計算されたプロパティの名前も分割代入で使用できます。

```js
const key = "z";
const { [key]: foo } = { z: "bar" };

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

#### 無効な JavaScript 識別子をプロパティ名として使用する

JavaScript で有効な代替識別子を与えることにより、JavaScript で有効ではない識別子であるプロパティ名を分割代入で使用できます。

```js
const foo = { "fizz-buzz": true };
const { "fizz-buzz": fizzBuzz } = foo;

console.log(fizzBuzz); // true
```

### プリミティブ値の分割代入

オブジェクトの分割代入は、プロパティへのアクセスとほぼ等価です。 これは、プリミティブ値を分割しようとすると、値が対応するラッパーオブジェクトに取得され、プロパティはラッパーオブジェクトにアクセスされることを意味しています。

```js
const { a, toFixed } = 1;
console.log(a, toFixed); // undefined ƒ toFixed() { [native code] }
```

プロパティへのアクセシビリティと同様に、`null` や `undefined` を分割代入すると `TypeError` が発生します。

```js
const { a } = undefined; // TypeError: Cannot destructure property 'a' of 'undefined' as it is undefined.
const { a } = null; // TypeError: Cannot destructure property 'b' of 'null' as it is null.
```

これは、パターンが空のときにも起こります。

```js
const {} = null; // TypeError: Cannot destructure 'null' as it is null.
```

#### 配列とオブジェクトの分割代入の組み合わせ

配列とオブジェクトの分割代入は組み合わせることができます。配列 `props` の 3 番目の要素にあるオブジェクトの `name` プロパティが欲しい場合、次の操作ができます。

```js
const props = [
  { id: 1, name: "Fizz" },
  { id: 2, name: "Buzz" },
  { id: 3, name: "FizzBuzz" },
];

const [, , { name }] = props;

console.log(name); // "FizzBuzz"
```

#### オブジェクトが分割されるときにはプロトタイプチェーンが参照される

オブジェクトが分割されるときで、自分自身のプロパティがアクセスされない場合は、プロトタイプチェーンを辿って参照が続けられます。

```js
const obj = {
  self: "123",
  \_\_proto\_\_: {
    prot: "456",
  },
};
const { self, prot } = obj;
// self "123"
// prot "456" (プロトタイプチェーンへのアクセス)
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-destructuring-assignment |
| ECMAScript Language Specification # sec-destructuring-binding-patterns |

ブラウザーの互換性
---------

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

関連情報
----

* 代入演算子
* "ES6 in Depth: Destructuring" on hacks.mozilla.org


左シフト代入 (<<=) - JavaScript

左シフト代入 (<<=)
============

左シフト代入演算子 (`<<=`) は、指定された数だけビットを左に移動し、結果を変数に代入します。

試してみましょう
--------

構文
--

```js
x <<= y; // x = x << y
```

例
-

### 左シフト代入の使用

```js
let a = 5;
// 00000000000000000000000000000101

a <<= 2; // 20
// 00000000000000000000000000010100
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

ブラウザーの互換性
---------

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

関連情報
----

* JavaScript ガイドの代入演算子
* 左シフト演算子


プロパティアクセサー - JavaScript

プロパティアクセサー
==========

**プロパティアクセサー**はオブジェクトのプロパティへのアクセスを提供するもので、ドット表記法またはブラケット表記法を使用します。

試してみましょう
--------

構文
--

```js
object.property;
object["property"];
```

解説
--

オブジェクトは実際には*連想配列* (別名 *map*、 *dictionary*、 *hash*、 *lookup table*) とみなすことができます。この配列における*キー*はオブジェクトのプロパティ名です。

一般的に、オブジェクトのプロパティについて説明する際には、プロパティとメソッドを区別します。しかし、プロパティとメソッドの区別は慣習的なものにすぎません。メソッドは呼び出すことができるプロパティです (例えば、値として `Function` インスタンスへの参照を持っているようなものです)。

プロパティにアクセスするには、*ドット表記法*と*ブラケット表記法*の 2 通りがあります。

### ドット表記法

`object.property` の構文では、 `property` は有効な JavaScript の 識別子でなければなりません。 (ECMAScript 標準では、プロパティの名前は技術的には "IdentifierNames" であり、 "Identifiers" ではないので、予約語を使用することができますがお勧めしません)。例えば、 `object.$1` は有効であるのに対し、 `object.1` は有効ではありません。

```js
const variable = object.property_name;

object.property_name = value;
```

```js
const object = {};

object.$1 = 'foo';
console.log(object.$1);  // 'foo'

object.1 = 'bar';        // SyntaxError
console.log(object.1);   // SyntaxError
```

ここで、 `createElement` というメソッドを `document` から取得し、呼び出します。

```js
document.createElement("pre");
```

数値リテラルに対してメソッドを使用する場合で、その数値リテラルに指数や小数点がない場合、メソッド呼び出しをするドットの前にホワイトスペースを入れることで、ドットが小数点とみなされることを防ぐことができます。

```js
77 .toExponential();
// or
77
.toExponential();
// or
(77).toExponential();
// or
77..toExponential();
// or
77.0.toExponential();
// 77.と77.0は同じものとして評価されます
```

### ブラケット表記法

`object[property_name]` の構文では、 `property_name` は文字列またはシンボルです。ですから、これは任意の文字列、例えば `'1foo'`、`'!bar!'`、または `' '` (空白) であっても構いません。

```js
const variable = object[property_name];
object[property_name] = value;
```

これは前の例とまったく同じです。

```js
document["createElement"]("pre");
```

ブラケット表記法の前には空白を入れることができます。

```js
document ["createElement"]("pre");
```

### プロパティ名

プロパティ名は文字列またはシンボルです。それ以外の値は、数値を含めて、文字列へ強制変換されます。これは `'value'` を出力します。 `1` が `'1'` に強制変換されるからです。

```js
let object = {};
object["1"] = "value";
console.log(object[1]);
```

こちらも `'value'` を出力します。`foo` と `bar` は同じ文字列に変換されるからです。

```js
let foo = { unique\_prop: 1 },
  bar = { unique\_prop: 2 },
  object = {};
object[foo] = "value";
console.log(object[bar]);
```

SpiderMonkey JavaScript エンジンでは、この文字列は "`[object Object]`" となります。

### メソッドのバインド

メソッドは、そのメソッドが所属するオブジェクトにバインドされているわけではありません。特に、 `this` はメソッド内で固定されていません。つまり、 `this` は必ずしもそのメソッドを含んでいるオブジェクトを参照しているとは限りません。 `this` は関数呼び出し時に「渡される」ものです。メソッドのバインドを参照してください。

例
-

### ブラケット表記法と `eval`

JavaScript 初心者はしばしば、代わりにブラケット表記法を使えるところで `eval()` (en-US) を使用してしまう間違いを犯します。

例えば、以下のような構文がたくさんのスクリプトで見られます。

```js
x = eval("document.forms.form\_name.elements." + strFormControl + ".value");
```

`eval()` は低速であり、可能な限り避けるべきです。また、 `strFormControl` は ID を必要としますが、フォームコントロールの名前と `id` は必須ではありません。代わりにブラケット表記法を使った方が良いでしょう。

```js
x = document.forms["form\_name"].elements[strFormControl].value;
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-property-accessors |

ブラウザーの互換性
---------

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

関連情報
----

* `Object`
* `Object.defineProperty()`
* オプショナルチェイニング


加算 (+) - JavaScript

加算 (+)
======

**加算 (`+`)** 演算子は、数値オペランドの合計または文字列の連結を生成します。

試してみましょう
--------

構文
--

```js
x + y
```

解説
--

演算子 `+` は数値の加算と文字列の連結という 2 つの異なる操作のためにオーバーロードされています。評価するとき、まず両方のオペランドをプリミティブに変換します。その後、 2 つのオペランドの型がテストされます。

* 一方が文字列の場合、もう一方のオペランドも文字列に変換され、連結されます。
* もし両方が長整数であれば、長整数同士の加算が行われます。一方が長整数で、もう一方が長整数でない場合、`TypeError` 例外が発生します。
* そうでない場合は、両辺が数値へ変換され、数値同士の加算が行われます。

文字列の連結はテンプレートリテラルや `String.prototype.concat()` と等価だと思われがちですが、そうではありません。加算は `valueOf()` を優先的に呼び出して、式をプリミティブに変換します。一方、テンプレートリテラルと `concat()` は `toString()`を優先的に呼び出し、式を文字列に変換します。式が `@@toPrimitive` メソッドを持っている場合、文字列連結は `"default"` をヒントとしてそれを呼び出しますが、テンプレートリテラルは `"string"` を使用します。これは、文字列表現とプリミティブ表現が異なるオブジェクト、例えば、 Temporal のように `valueOf()` メソッドが例外を発生するようなオブジェクトにとって重要です。

```js
const t = Temporal.Now.instant();
"" + t; // TypeError が発生
`${t}`; // '2022-07-31T04:48:56.113918308Z'
"".concat(t); // '2022-07-31T04:48:56.113918308Z'
```

`"" + x` を使用して文字列に変換を行わないことをお勧めします。

例
-

### 数値の加算

```js
// 数値 + 数値 -> 加算
1 + 2; // 3

// 論理値 + 数値 -> 加算
true + 1; // 2

// 論理値 + 論理値 -> 加算
false + false; // 0
```

### 長整数の加算

```js
// 長整数 + 長整数 -> 加算
1n + 2n; // 3n

// 長整数 + 数値 -> TypeError が発生
1n + 2; // TypeError: Cannot mix BigInt and other types, use explicit conversions

// 長整数を長整数以外に加算する場合は、どちらかのオペランドを変換する
1n + BigInt(2); // 3n
Number(1n) + 2; // 3
```

### 文字列の連結

```js
// 文字列 + 文字列 -> 連結
"foo" + "bar"; // "foobar"

// 数値 + 文字列 -> 連結
5 + "foo"; // "5foo"

// 文字列 + 論理値 -> 連結
"foo" + false; // "foofalse"

// 文字列 + 数値 -> 連結
"2" + 2; // "22"
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-addition-operator-plus |

ブラウザーの互換性
---------

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

関連情報
----

* 減算演算子
* 除算演算子
* 乗算演算子
* 剰余演算子
* べき乗演算子
* インクリメント演算子
* デクリメント演算子
* 単項マイナス演算子
* 単項プラス演算子


小なり (<) - JavaScript

小なり (<)
=======

小なり演算子 (`<`) は、左辺のオペランドが右辺のオペランドより小さい場合は `true` を返し、それ以外の場合は `false` を返します。

試してみましょう
--------

構文
--

```js
x < y;
```

解説
--

オペランドは、抽象関係比較アルゴリズムを使用して比較されます。以下に大まかに要約します。

* 最初に、オブジェクトは `Symbol.ToPrimitive` の `hint` 引数を `'number'` として使用してプリミティブに変換されます。
* 両方の値が文字列である場合、それらに含まれる Unicode コードポイントの値に基づいて、文字列として比較されます。
* それ以外の場合、 JavaScript は非数値型を数値に変換しようとします。
    + 論理値 `true` および `false` は、それぞれ 1 および 0 に変換されます。
    + `null` は 0 に変換されます。
    + `undefined` は `NaN` に変換されます。
    + 文字列は、含まれている値に基づいて変換され、数値が含まれていない場合は `NaN` として変換されます。
* いずれかの値が `NaN` の場合、演算子は `false` を返します。
* それ以外の場合、値は数値として比較されます。
例
-

### 文字列と文字列の比較

```js
console.log("a" < "b"); // true
console.log("a" < "a"); // false
console.log("a" < "3"); // false
```

### 文字列と数値の比較

```js
console.log("5" < 3); // false
console.log("3" < 3); // false
console.log("3" < 5); // true

console.log("hello" < 5); // false
console.log(5 < "hello"); // false

console.log("5" < 3n); // false
console.log("3" < 5n); // true
```

### 数値と数値の比較

```js
console.log(5 < 3); // false
console.log(3 < 3); // false
console.log(3 < 5); // true
```

### Number と BigInt の比較

```js
console.log(5n < 3); // false
console.log(3 < 5n); // true
```

### 論理値、null、undefined、NaN の比較

```js
console.log(true < false); // false
console.log(false < true); // true

console.log(0 < true); // true
console.log(true < 1); // false

console.log(null < 0); // false
console.log(null < 1); // true

console.log(undefined < 3); // false
console.log(3 < undefined); // false

console.log(3 < NaN); // false
console.log(NaN < 3); // false
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

ブラウザーの互換性
---------

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

関連情報
----

* 大なり演算子
* 大なりイコール演算子
* 小なりイコール演算子


typeof - JavaScript

typeof
======

**`typeof`** 演算子は、未評価のオペランドの型を示す文字列を返します。

試してみましょう
--------

構文
--

`typeof` 演算子の後に、オペランドを続けて書きます。

```js
typeof operand;
typeof(operand);
```

### 引数

`operand`

型を返すオブジェクトまたはプリミティブ型を表す式です。

解説
--

以下は `typeof` が返す可能性がある値の一覧です。型とプリミティブの詳細については、JavaScript のデータ構造のページも参照してください。

| 型 | 結果 |
| --- | --- |
| Undefined | `"undefined"` |
| Null | `"object"` (下記参照) |
| 論理値 | `"boolean"` |
| Number | `"number"` |
| BigInt (ECMAScript 2020 の新機能) | `"bigint"` |
| 文字列 | `"string"` |
| シンボル (ECMAScript 2015 の新機能) | `"symbol"` |
| 関数 オブジェクト (ECMA-262 の用語では [[Call]] を実装) | `"function"` |
| その他のオブジェクト | `"object"` |

**メモ:** ECMAScript 2019 およびそれ以前の実装では、呼び出し可能な標準外のオブジェクトに対して、`typeof` が任意の実装定義の文字列値を返すことを許可していました。

実際にこれを利用したブラウザーとして知られているのは、古い Internet Explorer だけです。（下記参照）

例
-

### 基本的な使い方

```js
// 数値
typeof 37 === "number";
typeof 3.14 === "number";
typeof 42 === "number";
typeof Math.LN2 === "number";
typeof Infinity === "number";
typeof NaN === "number"; // "Not-A-Number" であるにもかかわらず。
typeof Number("1") === "number"; // Number は数値に型強制できない値を含めて、
typeof Number("shoe") === "number"; // あらゆるものを数字に解釈します。

typeof 42n === "bigint";

// 文字列
typeof "" === "string";
typeof "bla" === "string";
typeof `template literal` === "string";
typeof "1" === "string"; // 文字列内の数値は文字列型のままです。
typeof typeof 1 === "string"; // typeof は常に文字列を返します。
typeof String(1) === "string"; // String は何でも文字列に変換するので、toString よりも安全です。

// 論理値
typeof true === "boolean";
typeof false === "boolean";
typeof Boolean(1) === "boolean"; // Boolean は、値が真値か偽値かに基づいて変換します。
typeof !!1 === "boolean"; // ! (論理 NOT) を 2 回呼び出すと Boolean() と同等になります。

// シンボル
typeof Symbol() === "symbol";
typeof Symbol("foo") === "symbol";
typeof Symbol.iterator === "symbol";

// Undefined
typeof undefined === "undefined";
typeof declaredButUndefinedVariable === "undefined";
typeof undeclaredVariable === "undefined";

// オブジェクト
typeof { a: 1 } === "object";

// Array.isArray または Object.prototype.toString.call を使用して、
// 通常のオブジェクトと配列を区別します。
typeof [1, 2, 4] === "object";

typeof new Date() === "object";
typeof /regex/ === "object"; // 過去の実装は正規表現の章を参照してください。

// 以下のようなものは、紛らわしく、危険で、無駄なものです。これらは使用しないようにしてください。
typeof new Boolean(true) === "object";
typeof new Number(1) === "object";
typeof new String("abc") === "object";

// 関数
typeof function () {} === "function";
typeof class C {} === "function";
typeof Math.sin === "function";
```

### `typeof null`

```js
// JavaScript の初期からの実装に基づく
typeof null === "object";
```

JavaScript の最初の実装では、JavaScript の値は型タグと値で表現されていました。オブジェクトの型タグは `0` で、`null` は NULL ポインター (ほとんどのプラットフォームで `0x00`) として表されていました。その結果、`null` はタグの型として `0` を持っていたため、`typeof` の戻り値は `"object"` です。(リファレンス)

ECMAScript の修正案が (オプトインを使用して) 提案されましたが、却下されました。それは `typeof null === 'null'` という結果になるものでした。

### `new` 演算子の使用

```js
// Function コンストラクターを除くすべてのコンストラクター関数は、
// 常に typeof 'object' です
let str = new String("String");
let num = new Number(100);

typeof str; // 'object' を返す
typeof num; // 'object' を返す

let func = new Function();

typeof func; // 'function' を返す
```

### 構文で括弧が必要な場合

```js
// 式のデータ型を特定するために、かっこを使用することができます。
let iData = 99;

typeof iData + " Wisen"; // 'number Wisen'
typeof (iData + " Wisen"); // 'string'
```

### 正規表現

呼び出し可能な正規表現は、一部のブラウザーにおける標準外の追加機能でした。

```js
typeof /s/ === "function"; // Chrome 1-12 ECMAScript5.1 に非準拠
typeof /s/ === "object"; // Firefox 5+ ECMAScript 5.1 に準拠
```

### エラー

ECMAScript 2015 より前では、`typeof` は常にそれが供給されたオペランドの文字列を返すことが保証されていました。宣言されていない識別子があっても、`typeof` は `'undefined'` を返します。`typeof` を使用すると、エラーは発生しません。

 しかしながら、ブロックスコープの `let` と
 `const` が追加されたことで、変数が宣言される前のブロック内で `let` と `const` に `typeof` を使用すると（またはクラスに `typeof` を使用すると）、 `ReferenceError` が発生します。ブロックスコープ内の変数は、ブロックの開始から初期化が処理されるまで「一時的なデッドゾーン」にあり、その間にアクセスされるとエラーが発生します。

```js
typeof undeclaredVariable === "undefined";

typeof newLetVariable; // ReferenceError
typeof newConstVariable; // ReferenceError
typeof newClass; // ReferenceError

let newLetVariable;
const newConstVariable = "hello";
class newClass {}
```

### 例外

現在のブラウザーではすべて、標準外のホストオブジェクト `document.all` は `undefined` 型になります。

```js
typeof document.all === "undefined";
```

仕様では、標準外のオブジェクトのために独自の型タグが設定できるようにしていますが、定義済みの型タグとは異なる必要があります。 `document.all` が `'undefined'` という型であるというのは、ウェブ標準では元の ECMA JavaScript 標準において「故意の違反」として分類されています。

### 実際の使い方

`typeof` は非常に便利ですが、汎用性はそれほど高くありません。たとえば、`typeof([])` は `typeof(new Date())` や `typeof(/abc/)` などと同様に `'object'` になります。

型のチェックをより具体的にするためには、実用レベルのコードで使用するための `typeof` ラッパーは以下のようになります。（`obj` が存在する場合）

```js
function type(obj, fullClass) {
  // obj の toPrototypeString() を取得します。（すべての型を処理します）
  if (showFullClass && typeof obj === "object") {
    return Object.prototype.toString.call(obj);
  }
  if (obj == null) {
    return (obj + "").toLowerCase();
  } // 暗黙の toString() 変換

  var deepType = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
  if (deepType === "generatorfunction") {
    return "function";
  }

  // 過剰な特異性を防いでください。(例えば、[object HTMLDivElement] など)
  // 関数的な正規表現 (Android 2.3 以前)、関数的な <object> 要素 (Chrome 57 以前, Firefox 52 以前) などを考慮してください。
  // String.prototype.match は普遍的にサポートされています。

  return deepType.match(
    /^(array|bigint|date|error|function|generator|regexp|symbol)$/,
  )
    ? deepType
    : typeof obj === "object" || typeof obj === "function"
      ? "object"
      : typeof obj;
}
```

存在しない変数をチェックすると、`ReferenceError` が発生するため、`typeof nonExistentVar === 'undefined'` を使用します。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-typeof-operator |

ブラウザーの互換性
---------

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

### IE 固有のメモ

IE 6、7、8 では、以下のように多くのホストオブジェクトがオブジェクト型であり、関数ではありません。

```js
typeof alert === "object";
```

一部の標準外 IE プロパティは他の値を返します。(tc39/ecma262#1440 (comment))

```js
typeof window.external.AddSearchProvider === "unknown";
typeof window.external.IsSearchProviderInstalled === "unknown";
```

関連情報
----

* `instanceof`
* `document.all` willful violation of the standard


右シフト (>>) - JavaScript

右シフト (>>)
=========

**右シフト演算子 (`>>`)** は、1つ目のオペランドを指定されたビット数だけ右にずらします。右にずらしてあふれたビットは廃棄されます。最も左のビットをコピーしながらずれて入ります。最も左のビットが以前の最も左のビットと同じになるため、符号ビット (最も左のビット) は変化しません。よって「符号維持」という名前です。

試してみましょう
--------

構文
--

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

解説
--

この演算子は、1 つ目のオペランドを指定されたビット数だけ右にずらします。右にずらしてあふれたビットは廃棄されます。最も左のビットをコピーしながらずれて入ります。最も左のビットが以前の最も左のビットと同じになるため、符号ビット (最も左のビット) は変化しません。よって「符号維持」という名前です。

例えば、 `9 >> 2` は 2 となります。
```

.    9 (10 進数): 00000000000000000000000000001001 (2 進数)
                  --------------------------------
9 >> 2 (10 進数): 00000000000000000000000000000010 (2 進数) = 2 (10 進数)
```

同様に、 `-9 >> 2` は符号が保存されるため、 `-3` になります。
```

.    -9 (10 進数): 11111111111111111111111111110111 (2 進数)
                   --------------------------------
-9 >> 2 (10 進数): 11111111111111111111111111111101 (2 進数) = -3 (10 進数)
```

例
-

### 右シフトの使用

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

仕様書
---

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

ブラウザーの互換性
---------

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

関連情報
----

* ビット演算子 (JavaScript ガイド)
* 右シフト代入演算子


this - JavaScript

this
====

**関数の `this` キーワード** は、JavaScript ではほかの言語と少々異なる動作をします。また、strict モードであるかどうかでも違いがあります。

ほとんどの場合、`this` の値はどのように関数が呼ばれたかによって決定されます (実行時結合)。これは実行時に代入によって設定することはできず、関数が呼び出されるたびに異なる可能性があります。ES5 では `bind()` メソッドが導入され、関数がどのように呼ばれたかに関係なく `this` の値を設定するすることができるようになり、ES2015 では、自身では `this` の結び付けを行わないアロー関数が導入されました (これは包含する構文上のコンテキストの `this` の値を保持します)。

試してみましょう
--------

構文
--
```

this
```

### 値

strict モードでない場合は、実行コンテキスト (グローバル、関数、eval) のプロパティで、常にオブジェクトへの参照です。 strict モードではどのような値でも取り得ます。

解説
--

### グローバルコンテキスト

グローバル実行コンテキスト (すべての関数の外側) では、strict モードであるかどうかにかかわらず、`this` はグローバルオブジェクトを参照します。

```js
// ウェブブラウザーでは window オブジェクトもグローバルオブジェクトです。
console.log(this === window); // true

a = 37;
console.log(window.a); // 37

this.b = "MDN";
console.log(window.b); // "MDN"
console.log(b); // "MDN"
```

**メモ:** コードが実行されている現在のコンテキストに関係なく、グローバルの `globalThis` プロパティを使用していつでも簡単にグローバルオブジェクトを取得できます。

### 関数コンテキスト

関数内での `this` の値は、関数の呼び出し方によって異なります。

下記のコードは strict モードではないため、また呼び出し時に `this` の値が設定されないため、`this` は既定でグローバルオブジェクトとなり、これはブラウザーでは `window` です。

```js
function f1() {
  return this;
}

// ブラウザー上で
f1() === window; // true

// Node 上で
f1() === global; // true
```

ただし strict モードでは、実行コンテキストに入るときに `this` 値が設定されていないと、以下の例のように `undefined` のままになります。

```js
function f2() {
  "use strict"; // strict モードにする
  return this;
}

f2() === undefined; // true
```

**メモ:** 二番目の例において、`this` が `undefined` となるのは `f2` が直接呼び出されており、オブジェクトのメソッドやプロパティ (例えば `window.f2()`) ではないためです。この機能は初めて strict モードへの対応が始まったとき、一部のブラウザーが実装していませんでした。結果的に、これらのブラウザーは不正確に `window` オブジェクトを返していました。

関数の呼び出し時に `this` の値を特定の値に設定するには、以下の例のように `call()` または `apply()` を使用します。

### クラスコンテキスト

クラスは関数の機能であるため、クラスと関数の `this` の動作は似ています。ただし、いくつかの違いと注意点があります。

クラスのコンストラクター内では、`this` は通常のオブジェクトです。クラス内のすべて静的でないメソッドは `this` のプロトタイプに追加されます。

```js
class Example {
  constructor() {
    const proto = Object.getPrototypeOf(this);
    console.log(Object.getOwnPropertyNames(proto));
  }
  first() {}
  second() {}
  static third() {}
}

new Example(); // ['constructor', 'first', 'second']
```

**メモ:** 静的メソッドは `this` のプロパティではありません。クラス自身のプロパティです。

### 派生クラス

基本クラスのコンストラクターとは異なり、派生コンストラクターには初期の `this` の結び付けがありません。`super()` を呼び出すとコンストラクター内に `this` の結び付けが作成され、基本的に以下のコードを評価する効果があります。ここで、Base は継承されたクラスです。

```js
this = new Base();
```

**警告:** `this` を `super()` の呼び出しの前に参照すると、エラーが発生します。

派生クラスはでは `super()` を呼び出す前に return をしてはいけません。ただし、 `Object` を返す場合やコンストラクターがない場合を除きます。

```js
class Base {}
class Good extends Base {}
class AlsoGood extends Base {
  constructor() {
    return { a: 5 };
  }
}
class Bad extends Base {
  constructor() {}
}

new Good();
new AlsoGood();
new Bad(); // 参照エラー
```

例
-

### 関数コンテキスト内の this

```js
// オブジェクトを call や apply の最初の引数として渡すと、this がそれに結び付けられます。
var obj = { a: "Custom" };

// 変数を定義すると、その変数がグローバルの window のプロパティとして割り当てられます。
var a = "Global";

function whatsThis() {
  return this.a; // this の値は関数の呼び出し方によって変わります
}

whatsThis(); // 'Global' はこの関数では this として設定されていないので、既定でグローバルの window オブジェクトになります
whatsThis.call(obj); // 'Custom' が関数内の this として obj に設定されています
whatsThis.apply(obj); // 'Custom' が関数内の this として obj に設定されています
```

### this とオブジェクト変換

```js
function add(c, d) {
  return this.a + this.b + c + d;
}

var o = { a: 1, b: 3 };

// 最初の引数は 'this' として使用する
// オブジェクトで、続く引数は関数呼び出しの
// 引数として使用されます。
add.call(o, 5, 7); // 16

// 最初の引数は 'this' として使用する
// オブジェクトで、二番目の引数は関数呼び出しの
// 引数として使用される配列です。
add.apply(o, [10, 20]); // 34
```

なお、 strict モードでない場合、`call` と `apply` は、`this` として渡された値がオブジェクトではないと、内部の `ToObject` 操作を利用してオブジェクトに変換しようします。`7` や `'foo'` のようなプリミティブが渡された場合、関連するコンストラクターを使用してオブジェクトに変換されます。たとえば、プリミティブの数値である `7` は `new Number(7)` であるかのようにオブジェクトに変換され、文字列の `'foo'` は `new String('foo')` であるかのようにオブジェクトに変換されます。

```js
function bar() {
  console.log(Object.prototype.toString.call(this));
}

bar.call(7); // [object Number]
bar.call("foo"); // [object String]
bar.call(undefined); // [object global]
```

### `bind` メソッド

ECMAScript 5 で `Function.prototype.bind()` が導入されました。`f.bind(someObject)` の呼び出しは、`f` と同じ内部とスコープを持つ新しい関数を生成し、ここが `this` が発生するオリジナルの関数ですが、関数がどのように使われるかにかかわらず、新しい関数では `bind` の最初の引数に永続的にバインドされます。

```js
function f() {
  return this.a;
}

var g = f.bind({ a: "azerty" });
console.log(g()); // azerty

var h = g.bind({ a: "yoo" }); // bind は一度しか機能しない
console.log(h()); // azerty

var o = { a: 37, f: f, g: g, h: h };
console.log(o.a, o.f(), o.g(), o.h()); // 37,37, azerty, azerty
```

### アロー関数

アロー関数では、`this` はそれを囲む構文上のコンテキストの `this` の値が設定されます。グローバルコードでは、グローバルオブジェクトが設定されます。

```js
var globalObject = this;
var foo = () => this;
console.log(foo() === globalObject); // true
```

**メモ:** アロー関数の呼び出し時に `this` 引数が `call`, `bind`, `apply` に渡されても無視されます。呼び出しに引数を加えることはできますが、最初の引数 (`thisArg`) は `null` を設定してください。

```js
// オブジェクトのメソッドとして呼び出す。
var obj = { func: foo };
console.log(obj.func() === globalObject); // true

// call を使用して this の設定を試みる
console.log(foo.call(obj) === globalObject); // true

// bind を使用して this の設定を試みる
foo = foo.bind(obj);
console.log(foo() === globalObject); // true
```

何があっても、`foo` の `this` は生成されたときの値が設定されています (上記の例ではグローバルオブジェクトです)。同様のことが、ほかの関数内で生成したアロー関数にも適用されます。それらの `this` には、それを包含する構文上のコンテキストのものになります。

```js
// this を返す関数を返す bar メソッドを持つ
// obj を生成します。返された関数はアロー関数
// として生成されているため、その this は
// それを包含する関数の this に永続的に拘束
// されます。bar の値は呼び出し時に設定でき、
// 返値の関数の値に順に設定します。
var obj = {
  bar: function () {
    var x = () => this;
    return x;
  },
};

// bar を obj のメソッドとして呼び出す際、その this を obj に設定します
// 返値の関数への参照を fn に割り当てます。
var fn = obj.bar();

// strict モードでは、this を設定せずに fn を呼び出すと
// 通常はグローバルオブジェクトか undefined が既定値となります。
console.log(fn() === obj); // true

// しかし obj のメソッドを call することなく参照するのは要注意です。
var fn2 = obj.bar;
// するとアロー関数の呼び出しで this は bar の
// this に従うため window と同じになります。
console.log(fn2()() == window); // true
```

上記では、関数 (この無名関数を A と呼びます) に `obj.bar` が返すアロー関数として生成されたほかの関数 (この無名関数を B と呼びます) を割り当てています。結果として、呼び出されたときに関数 B の `this` は、永続的に `obj.bar` (関数 A) の `this` が設定されます。返された関数 (関数 B) が呼びされるとき、その `this` は常に最初に設定されたものになります。上記のコード例では、関数 B の `this` は `obj` である関数 A の `this` が設定されているため、通常はその `this` に `undefined` かグローバルオブジェクト (または、以前の例のグローバルコンテキストのように、いずれかのメソッド) が設定されますが、`obj` の設定が残ります。

### オブジェクトのメソッドとして

関数がオブジェクトのメソッドとして呼び出されるとき、その `this` にはメソッドが呼び出されたオブジェクトが設定されます。

次の例では、`o.f()` が起動したとき、関数内の `this` には、`o` オブジェクトが関連付けられます。

```js
var o = {
  prop: 37,
  f: function () {
    return this.prop;
  },
};

console.log(o.f()); // 37
```

この動作は、関数定義の方法や場所に全く影響を受けないことに注意してください。前述の例では、`o` の定義中に `f` メンバーとして関数をインラインに定義しています。しかし、関数を最初に定義して、後から `o.f` に付け足すことができます。その結果は同じ動作になります。

```js
var o = { prop: 37 };

function independent() {
  return this.prop;
}

o.f = independent;

console.log(o.f()); // 37
```

これは、関数が `o` の `f` のメンバーとして呼び出されることだけが重要なことを示しています。

同様に、`this` の関連付けは、最も直近のメンバー参照にのみ影響を受けます。次の例では、関数が呼び出すとき、オブジェクト `o.b` の `g` メソッドとして呼び出しています。実行時に、関数内の `this` は `o.b` を参照します。オブジェクト自体が `o` のメンバーであるという事実は何の意味もありません。最も直近の参照のみが重要なのです。

```js
o.b = { g: independent, prop: 42 };
console.log(o.b.g()); // 42
```

#### オブジェクトのプロトタイプチェーン上の `this`

同じ概念が、オブジェクトのプロトタイプチェーンのどこかに定義されたメソッドにも当てはまります。メソッドがオブジェクトのプロトタイプチェーン上にあった場合、メソッドがオブジェクト上にあるかのように、`this` はメソッドを呼び出したオブジェクトを参照します。

```js
var o = {
  f: function () {
    return this.a + this.b;
  },
};
var p = Object.create(o);
p.a = 1;
p.b = 4;

console.log(p.f()); // 5
```

この例では、変数 `p` に割り当てられたオブジェクト自身は `f` プロパティを持たず、プロトタイプから継承しています。しかし、`f` に対する検索が、最終的に `o` でその名前を持つメンバーを見つけることは重要ではありません。検索は `p.f` への参照から開始されるため、関数内の `this` は `p` として参照されるオブジェクトの値を取ります。`f` は `p` のメソッドとして呼ばれたため、その `this` は `p` を参照します。これは、JavaScript のプロトタイプ継承の興味深い機能です。

#### ゲッター/セッターと `this`

再度、同じ概念が、ゲッターやセッターから呼ばれる関数にも当てはまります。ゲッターやセッターとして使用される関数は、このプロパティを設定するか、または得られている元のオブジェクトに関連付けられている `this` を持ちます。

```js
function sum() {
  return this.a + this.b + this.c;
}

var o = {
  a: 1,
  b: 2,
  c: 3,
  get average() {
    return (this.a + this.b + this.c) / 3;
  },
};

Object.defineProperty(o, "sum", {
  get: sum,
  enumerable: true,
  configurable: true,
});

console.log(o.average, o.sum); // 2, 6
```

### コンストラクターとして

関数がコンストラクターとして (`new` キーワードとともに) 使用されたとき、その `this` は生成された新しいオブジェクトに関連付けられます。

**メモ:** コンストラクターの既定では、`this` で参照されるオブジェクトを返しますが、代わりにほかのオブジェクトを返すことができます (返値がオブジェクトではない場合、`this` オブジェクトが返されます)。

```js
/\*
 \* コンストラクターは下記のように動作します。
 \*
 \* function MyConstructor(){
 \* // 実際の関数本体のコードはこちらになります。
 \* // プロパティに代入することで、 |this| に必要な
 \* // プロパティを作成します。例えば、
 \* this.fum = "nom";
 \* // など...
 \*
 \* // 関数にオブジェクトを返す return 文があれば、
 \* // そのオブジェクトが |new| 式の結果になります。
 \* // そうでなければ、式の結果は現在 |this| に
 \* // バインドされているオブジェクトになります
 \* // (つまり、最もよく見られる一般的なケースです)。
 \* }
 \*/

function C() {
  this.a = 37;
}

var o = new C();
console.log(o.a); // 37

function C2() {
  this.a = 37;
  return { a: 38 };
}

o = new C2();
console.log(o.a); // 38
```

最後の例 (`C2`) では、構築中にオブジェクトを返しているので、`this` が結び付けられている新しいオブジェクトは単に破棄されています。(これは根本的に "`this.a = 37;`" 文を死んだコードにしてしまっています。これは実行されるので、正確には死んだコードではありませんが、外部への影響がありません。)

### DOM イベントハンドラーとして

関数がイベントハンドラとして使用された場合、その `this` はリスナーが配置されている要素に設定されます (`addEventListener()` 以外のメソッドで動的に追加されたリスナーについては、この規約に従わないブラウザーもあります)。

```js
// リスナーとして呼び出された場合は、関連づけられた要素を青にする
function bluify(e) {
  // 常に true
  console.log(this === e.currentTarget);
  // currentTarget と target が同じオブジェクトであれば true
  console.log(this === e.target);
  this.style.backgroundColor = "#A5D9F3";
}

// 文書内の各要素の一覧を取得
var elements = document.getElementsByTagName("\*");

// クリックリスナーとして bluify を追加することで、
// 要素をクリックすると青くなるようになる
for (var i = 0; i < elements.length; i++) {
  elements[i].addEventListener("click", bluify, false);
}
```

### インラインイベントハンドラー内

コードがインラインの on-イベントハンドラーから呼び出されたとき、その `this` にはリスナーが配置されている DOM 要素が設定されます。

```html
<button onclick="alert(this.tagName.toLowerCase());">Show this</button>
```

上記のアラートは `button` と表示します。ただし、外側のコードがこのように設定された `this` を持っているだけだということに注意してください。

```html
<button onclick="alert((function() { return this; })());">
  Show inner this
</button>
```

この場合、内側の関数の `this` は設定されていないので、グローバルの window オブジェクトを返します (つまり、`this` が呼び出しによって設定されていないので、非 strict モードの既定オブジェクトです)。

### クラス内の this

通常の関数と同様に、メソッド内の `this` の値は、どのように呼び出されるかによって異なります。クラス内の `this` が常にクラスのインスタンスを参照するように、この動作をオーバーライドしておくと便利な場合もあります。これを実現するには、コンストラクターでクラスのメソッドをバインドします。

```js
class Car {
  constructor() {
    // 違いを示すために sayHi ではなく sayBye をバインドする
    this.sayBye = this.sayBye.bind(this);
  }
  sayHi() {
    console.log(`Hello from ${this.name}`);
  }
  sayBye() {
    console.log(`Bye from ${this.name}`);
  }
  get name() {
    return "Ferrari";
  }
}

class Bird {
  get name() {
    return "Tweety";
  }
}

const car = new Car();
const bird = new Bird();

// メソッドの 'this' の値は呼び出し元に依存します
car.sayHi(); // Hello from Ferrari
bird.sayHi = car.sayHi;
bird.sayHi(); // Hello from Tweety

// バインドされたメソッドの場合、'this' は呼び出し元に依存しません
bird.sayBye = car.sayBye;
bird.sayBye(); // Bye from Ferrari
```

**メモ:** クラスは常に strict モードのコードです。これを定義せずに `this` でメソッドを呼び出すとエラーが発生します。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-this-keyword |

ブラウザーの互換性
---------

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

関連情報
----

* Strict モード
* Gentle
explanation of 'this' keyword in JavaScript
* グローバルコンテキストの取得: `globalThis`