文と宣言 - JavaScript

文と宣言
====

JavaScript アプリケーションは、適切な構文で書かれた文から構成されます。ひとつの文が数行に渡る場合もあります。また複数の文それぞれがセミコロンで区切られていれば 1 行となる場合もあります。そのキーワードはひとつではなく、キーワードのグループとなっています。

文と宣言（カテゴリ別）
-----------

アルファベット順リストは左サイドバーで確認できます。

### フロー制御

`return`

関数が返す値を指定します。

`break`

現在実行中のループ、`switch` による分岐、あるいはラベル文を終了し、その終了した文に続く文へとプログラムの制御を移行します。

`continue`

現在実行中のループ、またはラベル付きループで現在反復している文の実行を終了し、そのループの実行を次の反復から継続します。

`throw`

ユーザー定義の例外を発生させます。

`if...else`

与えられた条件が真の場合はある文を実行します。条件が偽の場合はまた別の文を実行できます。

`switch`

ある式を評価し、式の値を case 節と照らし合わせ、 case 節に関連付けられた文を実行します。

`try...catch`

実行を試み、例外が発生した際に行うべき処理を規定する文のブロックを記述します。

### 宣言

`var`

変数を宣言し、その変数をある値に初期化することもできます。

`let`

ブロックスコープを持つローカル変数を宣言し、その変数をある値に初期化することもできます。

`const`

読み取り専用の名前付き定数を宣言します。

### 関数とクラス

`function`

指定された仮引数を持つ関数を宣言します。

`function*`

イテレーターをより簡単に書けるジェネレーター関数です。

`async function`

指定した引数を持つの非同期関数を宣言します。

`async function*`

非同期ジェネレータ関数により、非同期のイテレーターをより簡単に書くことができます。

`class`

クラスを宣言します。

### 反復処理

`do...while`

テスト条件が偽と評価されるまで指定された文を実行するループを作成します。この条件は文が実行されたあとに評価されます。その結果、少なくとも 1 回は指定された文が実行されます。

`for`

丸括弧で囲まれ、セミコロンで区切られた 3 つの式と、それに続くループ内で実行される文から構成されるループを作成します。

`for...in`

オブジェクトの列挙可能なプロパティに対し任意の順番で反復処理を行います。それぞれ個別のプロパティに対し、文を実行できます。

`for...of`

反復可能オブジェクト (配列、配列風オブジェクト、イテレーターとジェネレーターを含む) を反復処理し、それぞれ個別のプロパティの値に対する実行文をともなった反復処理フックを呼び出します。

`for await...of`

非同期反復オブジェクト、配列風オブジェクト、イテレーターとジェネレーターを反復処理し、各固有のプロパティ値で実行する文を実行しつつ、カスタムイテレーションフックを実行する。

`while`

テスト条件が真と評価される間、指定した文を実行するループを作成します。この条件は文が実行される前に評価されます。

### その他

空文

空文は、文が必要ないが JavaScript の文法上 1 つの文が必要な場合に使います。

ブロック

ブロック文は 0 個以上の文をグループ化するのに使います。ブロックは 1 組の波括弧で囲みます。

式文

式文は、式を評価し、その結果を破棄します。これにより、関数の実行や変数の更新など、式に付随する効果を実行することができます。

`debugger`

利用可能なデバッグ機能を呼び出します。利用可能なデバッグ機能がない場合、この文は無効となります。

`export`

外部モジュールや別のスクリプトでインポートできるように、関数をエクスポートするのに使われます。

`import`

外部モジュールや別のスクリプトからエクスポートされる関数をインポートするのに使われます。

ラベル

`break` や `continue` 文を使う際に参照できる識別子を含む文を用意します。

`with`
非推奨

文のスコープチェーンを拡張します。

文と宣言の違いについて
-----------

この節では、 2 種類の構文を比較します。*文*と*宣言*です。これらは 2 つの独立した文法集合です。以下のものは宣言です。

* `let`
* `const`
* `function`
* `function*`
* `async function`
* `async function*`
* `class`
* `export` （注: モジュールの最上位にのみ現れます）
* `import` （注: モジュールの最上位にのみ現れます）

前述のうち、それ以外のものはすべて文です。

「文」と「宣言」という用語は、JavaScript の形式文法において厳密な意味を持ち、それがコードのどこに配置されるかに影響します。例えば、ほとんどの制御フロー構造では、本体は文だけを受け入れます。例えば `if...else` の分岐先などです。）

```js
if (条件)
  文1;
else
  文2;
```

もし、文の代わりに宣言を使用した場合、 `SyntaxError` となります。例えば、 `let` 宣言は文ではないので、 `if` 文の本体としてそのままの形を使用することはできません。

```js
if (条件)
  let i = 0; // SyntaxError: Lexical declaration cannot appear in a single-statement context
```

一方、`var` は文なので、それ自身で `if` 本体として使用することができます。

```js
if (条件)
  var i = 0;
```

宣言は「識別子と値を結びつける」ものであり、文は「アクションを実行する」ものであると考えることができます。なぜなら、`var` は通常の字句スコープの規則に従わないので、副作用を引き起こす可能性があるからです。グローバル変数の作成、既存の `var` で定義された変数の変更、ブロックの外から見える変数の定義（`var` で定義された変数はブロックスコープに入らないため）のような形式です。

他の例として、ラベルは文にのみ付けることができます。

```js
label: const a = 1; // SyntaxError: Lexical declaration cannot appear in a single-statement context
```

**メモ:** 関数宣言にラベルを持たせる古い文法がありますが、ウェブの現実との互換性のために標準化されただけです。

これを回避するには、宣言を中括弧で囲んで、ブロック文の一部にすることができます。

```js
label: {
  const a = 1;
}

if (条件) {
  let i = 0;
}
```

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

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

関連情報
----

* 演算子


JavaScript エラーリファレンス - JavaScript

JavaScript エラーリファレンス
====================

以下に、 JavaScript で発生するエラーのリストがあります。これらのエラーはデバッグを大いに助けてくれますが、報告される問題がいつも直ちに明快とは限りません。以下のページでは、これらのエラーについて詳しく説明します。どのエラーも `Error` オブジェクトを基礎としたオブジェクトであり、`name` と `message` を有しています。

ウェブコンソールに表示されたエラーには、コードにある問題を速やかに理解するのに役立つ、関連ページへのリンクが含まれていることがあります。

JavaScript のエラーを修正するための初心者向け導入用チュートリアルについては、何が間違っている? JavaScript のトラブルシューティングを参照してください。

エラーのリスト
-------

このリストでは、各ページが名前 (エラーの種別) とメッセージ (より詳細で読解可能なエラーメッセージ) によってリストアップされています。これら 2 つのプロパティが、エラーの理解と解決の出発点となります。詳細は、以下のリンクを参照してください！

* Error: Permission denied to access property "x"
* InternalError: too much recursion
* RangeError: argument is not a valid code point
* RangeError: invalid array length
* RangeError: invalid date
* RangeError: precision is out of range
* RangeError: radix must be an integer
* RangeError: repeat count must be less than infinity
* RangeError: repeat count must be non-negative
* ReferenceError: "x" is not defined
* ReferenceError: assignment to undeclared variable "x"
* ReferenceError: can't access lexical declaration`X' before initialization
* ReferenceError: deprecated caller or arguments usage
* ReferenceError: invalid assignment left-hand side
* ReferenceError: reference to undefined property "x"
* SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated
* SyntaxError: "use strict" not allowed in function with non-simple parameters
* SyntaxError: "x" is a reserved identifier
* SyntaxError: JSON.parse: bad parsing
* SyntaxError: Unexpected token
* SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
* SyntaxError: a declaration in the head of a for-of loop can't have an initializer
* SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
* SyntaxError: for-in loop head declarations may not have initializers
* SyntaxError: function statement requires a name
* SyntaxError: identifier starts immediately after numeric literal
* SyntaxError: illegal character
* SyntaxError: invalid regular expression flag "x"
* SyntaxError: missing ) after argument list
* SyntaxError: missing ) after condition
* SyntaxError: missing : after property id
* SyntaxError: missing ; before statement
* SyntaxError: missing = in const declaration
* SyntaxError: missing ] after element list
* SyntaxError: missing formal parameter
* SyntaxError: missing name after . operator
* SyntaxError: missing variable name
* SyntaxError: missing } after function body
* SyntaxError: missing } after property list
* SyntaxError: redeclaration of formal parameter "x"
* SyntaxError: return not in function
* SyntaxError: test for equality (==) mistyped as assignment (=)?
* SyntaxError: unterminated string literal
* TypeError: "x" has no properties
* TypeError: "x" is (not) "y"
* TypeError: "x" is not a constructor
* TypeError: "x" is not a function
* TypeError: "x" is not a non-null object
* TypeError: "x" is read-only
* TypeError: 'x' is not iterable
* TypeError: More arguments needed
* TypeError: Reduce of empty array with no initial value
* TypeError: X.prototype.y called on incompatible type
* TypeError: can't assign to property "x" on "y": not an object
* TypeError: can't define property "x": "obj" is not extensible
* TypeError: can't delete non-configurable array element
* TypeError: can't redefine non-configurable property "x"
* TypeError: cannot use 'in' operator to search for 'x' in 'y'
* TypeError: cyclic object value
* TypeError: invalid 'instanceof' operand 'x'
* TypeError: invalid Array.prototype.sort argument
* TypeError: invalid assignment to const "x"
* TypeError: property "x" is non-configurable and can't be deleted
* TypeError: setting getter-only property "x"
* URIError: malformed URI sequence
* Warning: -file- is being assigned a //# sourceMappingURL, but already has one
* Warning: unreachable code after return statement


関数 - JavaScript

関数
==

一般的に言うと、関数とは外部 (再帰の場合は内部) から *呼び出す* ことのできる「サブプログラム」です。プログラムそのもののように、関数は関数本体 (*function body*) と呼ばれる連続した文で構成されます。値を関数に*渡す*ことができ、関数は値を*返す*ことができます。

JavaScript において、関数は第一級オブジェクトです。すなわち、関数はオブジェクトであり、他のあらゆるオブジェクトと同じように操作したり渡したりすることができます。具体的には、関数は `Function` オブジェクトです。

より詳細な例や解説については、JavaScript の関数のガイドを参照してください。

解説
--

JavaScript におけるすべての関数は、実際には `Function` オブジェクトです。`Function` オブジェクトのプロパティとメソッドについての情報は `Function` をご覧ください。

初期値以外の値を返すためには、返す値を指定する `return` 文が関数内になくてはなりません。`return` 文を持たない関数は既定値を返します。コンストラクターが `new` キーワードとともに呼び出された場合、その `this` 引数が初期値となります。それ以外のすべての関数が既定で返す値は `undefined` です。

関数の仮引数 (parameter) には、関数呼び出しにおいて実引数 (*argument*) が渡されます。実引数は、関数に*値渡し*されます。関数の中で引数の値を変更しても、その変更はグローバルスコープもしくは呼び出し元の関数内には反映されません。オブジェクト参照も「値」ですが、こちらは特別です。参照されているオブジェクトのプロパティを関数の中で変更すると、次の例にあるように、その変更を関数の外部から見ることができます。

```js
/\* 関数 'myFunc' を宣言 \*/
function myFunc(theObject) {
  theObject.brand = "Toyota";
}

/\*
 \* 変数 'mycar' を宣言
 \* 新しいオブジェクトの生成と初期化
 \* 'mycar' への参照をオブジェクトに代入
 \*/
var mycar = {
  brand: "Honda",
  model: "Accord",
  year: 1998,
};

/\* 'Honda' を出力 \*/
console.log(mycar.brand);

/\* オブジェクト参照を関数に渡す \*/
myFunc(mycar);

/\*
 \* オブジェクトの 'brand' プロパティの値は関数によって
 \* 変更されたので 'Toyota' と出力される
 \*/
console.log(mycar.brand);
```

`this` キーワードは現在実行中の関数を参照しません。よって、その関数本体の中であっても、名前によって `Function` オブジェクトを参照しなければなりません。

関数の定義
-----

関数を定義するのにはいくつかの方法があります。

### 関数宣言 (`function` 文)

関数を宣言するための特殊な構文があります。(詳細は function 文を参照)

```js
function name([param[, param[, ... param]]]) {
   statements
}
```

`name`

関数名です。

`param`

関数に渡される引数の名前です。

`statements`

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

### 関数式 (`function` 式)

関数式は、関数宣言と似ており、同じ構文を持っています (詳細は関数式を参照)。関数式はより大きな式の一部になることもあります。「名前付き」の関数式を定義することもできます (例えばその名前はコールスタック内で使われるかもしれません) し、「無名の」関数式を定義することもできます。関数式はスコープの開始時に「巻き上げ」られないので、コード内でそれらが登場するより前に使用することはできません。

```js
function [name]([param[, param[, ... param]]]) {
   statements
}
```

`name`

関数名。省略することができ、その場合は関数は無名関数と見なされます。

`param`

関数に渡される引数の名前です。

`statements`

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

以下は**無名の**関数式の例です (`name` が使われていない)。

```js
var myFunction = function () {
  statements;
};
```

定義の中で名前を提供することで、**名前付きの**関数式を作ることも可能です。

```js
var myFunction = function namedFunction() {
  statements;
};
```

名前付きの関数式を作ることの利点の 1 つは、エラーに遭遇したとき、スタックトレースがその関数の名前を含めるため、エラーの発生源をより容易に特定できるということです。

ここまで見てきたように、どちらの例も `function` キーワードから開始されていません。 `function` から開始せずに関数を含んでいる文が関数式です。

関数が一度だけ使われるとき、一般的なパターンが即時実行関数式 (IIFE, Immediately Invoked Function Expression) です。

```js
(function () {
  statements;
})();
```

即時実行関数式は、関数を宣言した直後に実行する関数式です。

### ジェネレーター関数宣言 (`function*` 文)

ジェネレーター関数の宣言のための特別な構文です (詳細は `function* 文` を参照してください)。

```js
function\* name([param[, param[, ... param]]]) {
   statements
}
```

`name`

関数名。

`param`

関数に渡される引数の名前です。

`statements`

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

### ジェネレーター関数式 (`function*` 式)

ジェネレーター関数式は、ジェネレーター関数宣言と似ており、同じ構文を持っています （詳細は `function* 式` を参照してください）。

```js
function\* [name]([param[, param[, ... param]]]) {
   statements
}
```

`name`

関数名。省略することができ、その場合関数は無名関数と見なされます。

`param`

関数に渡される引数の名前です。

`statements`

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

### アロー関数式 (=>)

アロー関数式はより短い構文で、 `this` 値を語彙的に結合します (詳細はアロー関数を参照)。

```js
([param[, param]]) => {
   statements
}

param => expression
```

`param`

引数の名前。引数が 0 個の場合は `()` で示すことが必要です。引数が 1 個の場合のみ、丸括弧は必須ではありません。(例えば `foo => 1`)

`statements` または `expression`

複数の文は中括弧で括らなければなりません。単一の式では、中括弧は必須ではありません。式は、関数の暗黙的な返値でもあります。

### `Function` コンストラクター

**メモ:** `Function` コンストラクターによる関数の生成は推奨されません。これは、文字列として関数本体が必要であり、JS エンジンによる最適化を妨げたり、他の問題を引き起こしたりする場合があるためです。

他のすべてのオブジェクトと同じように、`new` 演算子を使って `Function` オブジェクトを作成することができます。

```js
new Function(arg1, arg2, ...argN, functionBody);
```

`arg1, arg2, ... argN`

関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。

`functionBody`

関数定義を構成する JavaScript 文を含む文字列。

`Function` コンストラクターを関数として (`new` 演算子を使わずに) 呼び出しても、コンストラクターとして呼び出すのと同じ効果があります。

### `GeneratorFunction` コンストラクター

**メモ:** `GeneratorFunction` はグローバルオブジェクトではありませんが、ジェネレーター関数のインスタンスから得ることができます (詳細は `GeneratorFunction` を参照してください)。

**メモ:** `GeneratorFunction` コンストラクターによる関数の生成は推奨されません。これは、文字列として関数本体が必要で、JS エンジンによる最適化を妨げたり、他の問題を引き起こしたりする場合があるためです。

他のすべてのオブジェクトと同じように、 `new` 演算子を使って `GeneratorFunction` オブジェクトを作成することができます。

```js
new GeneratorFunction(arg1, arg2, ...argN, functionBody);
```

`arg1, arg2, ... argN`

関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。例えば "`x`"、"`theValue`"、"`a,b`" などです。

`functionBody`

関数定義を構成する JavaScript 文を含む文字列です。

`Function` コンストラクターを関数として (`new` 演算子を使わずに) 呼び出しても、コンストラクターとして呼び出すのと同じ効果があります。

関数の引数
-----

### デフォルト引数

関数のデフォルト引数で、関数に値が渡されなかった場合や `undefined` が渡された場合に、既定値で初期化される形式上の引数を指定できます。詳細はデフォルト引数を参照してください。

### 残余引数

残余引数とは、不特定多数の引数を配列として受け取る構文です。詳細は残余引数を参照してください。

`arguments` オブジェクト
------------------

`arguments` オブジェクトを使って、関数内部で関数の引数を参照することができます。arguments を参照してください。

* `arguments`:
 現在実行中の関数に渡された引数を格納する配列風オブジェクト。
* `arguments.callee`:
 現在実行中の関数。
* `arguments.caller`:
 現在実行中の関数を呼び出した関数。
* `arguments.length`:
 関数に渡された引数の数。
メソッドの定義
-------

### ゲッターおよびセッター関数

ゲッター (アクセサーメソッド) およびセッター (ミューテーターメソッド) は、標準組み込みオブジェクトでもユーザー定義オブジェクトでも、新しいプロパティの追加に対応していれば定義することができます。ゲッターとセッターを定義するための構文は、オブジェクトリテラル構文を使用します。

get

オブジェクトのプロパティを、そのプロパティが検索されたときに呼び出される関数に束縛します。

set

あるオブジェクトのプロパティを、そのプロパティに代入しようとしたときに呼び出される関数に結びつけます。

### メソッド定義構文

ECMAScript 2015 からは、独自のメソッドを、ゲッターとセッターに似たより短い構文で定義することができます。詳細はメソッド定義を参照してください。

```js
var obj = {
  foo() {},
  bar() {},
};
```

コンストラクターと関数宣言と関数式
-----------------

以下のものを比較してみて下さい。

`Function` *コンストラクター*によって定義され、変数 `multiply` に代入された関数です。

```js
var multiply = new Function("x", "y", "return x \* y");
```

`multiply` と命名された関数の*関数宣言*です。

```js
function multiply(x, y) {
  return x \* y;
} // ここにセミコロンは必要ありません
```

変数 `multiply` に代入された、無名関数の*関数式*です。

```js
var multiply = function (x, y) {
  return x \* y;
};
```

変数 `multiply` に代入された、`func_name` と命名された関数式です。

```js
var multiply = function func\_name(x, y) {
  return x \* y;
};
```

### 相違点

これらはすべて、おおよそ同じ働きをしますが、いくつか微妙に異なる点があります。

関数名と関数が代入された変数の間には違いがあります。関数名は変えることができませんが、関数が代入された変数は再代入することができます。関数名は関数本体の内部でのみ使用することができます。関数本体の外側でそれを使用しようとするとエラー (その関数名がそれより前に `var` 文によって宣言されていれば `undefined`) になります。例えば、

```js
var y = function x() {};
alert(x); // throws an error
```

関数名は `Function` の toString メソッドによってシリアライズしたときにも現れます。

一方、関数が代入された変数はそのスコープ内でのみ有効で、そのスコープは関数が宣言されたスコープを含んでいることが保証されています。

4 つ目の例にあるように、関数名はその関数が代入される変数と違っていても構いません。互いの間に関連性はありません。関数宣言は同時にその関数名と同じ名前の変数を作成します。よって、関数式で定義されたものと違って、関数宣言で定義された関数は定義されたスコープ内でも、その名前によってアクセスできます。

`new Function` によって定義された関数は関数名を持ちません。しかし、JavaScript エンジンの SpiderMonkey では、その関数をシリアライズされた形式にすると "anonymous" という名前を持っているかのように表示されます。例えば、`alert(new Function())` はこのように出力されます。

```js
function anonymous() {}
```

この関数は実際には名前を持っていないので、`anonymous` は関数内部でアクセスできる変数ではありません。例えば、次の文はエラーになります。

```js
var foo = new Function("alert(anonymous);");
foo();
```

関数式や `Function` コンストラクターで定義されたものとは違い、関数宣言で定義された関数は、関数自体が宣言される前に使用することができます。例えば、

```js
foo(); // FOO! とアラート表示
function foo() {
  alert("FOO!");
}
```

関数式で定義された関数は現在のスコープを継承します。つまり、関数がクロージャを形成します。一方、`Function` コンストラクターで定義された関数は (あらゆる関数が継承する) グローバルスコープ以外はどんなスコープも継承しません。

```js
/\*
 \* Declare and initialize a variable 'p' (global)
 \* and a function 'myFunc' (to change the scope) inside which
 \* declare a varible with same name 'p' (current) and
 \* define three functions using three different ways:-
 \* 1. function declaration
 \* 2. function expression
 \* 3. function constructor
 \* each of which will log 'p'
 \*/
var p = 5;
function myFunc() {
  var p = 9;

  function decl() {
    console.log(p);
  }
  var expr = function () {
    console.log(p);
  };
  var cons = new Function("\tconsole.log(p);");

  decl();
  expr();
  cons();
}
myFunc();

/\*
 \* Logs:-
 \* 9 - for 'decl' by function declaration (current scope)
 \* 9 - for 'expr' by function expression (current scope)
 \* 5 - for 'cons' by Function constructor (global scope)
 \*/
```

関数式と関数宣言で定義された関数は一度しか解析されませんが、`Function` コンストラクターで定義された関数はそうではありません。つまり、`Function` コンストラクターに渡された関数本体を表す文字列が、評価されるたびに必ず解析されます。関数式は毎回クロージャを作成しますが、関数本体は再解析されないので、"`new Function(...)`" よりは関数式の方がまだ高速です。したがって `Function` コンストラクターはできる限り避けるべきでしょう。

ただし、`Function` コンストラクターの文字列を解析することで生成された関数内で入れ子にされている関数式や関数宣言は、繰り返し解析されないことに注意してください。例えば、

```js
var foo = new Function(
  "var bar = 'FOO!';\nreturn(function() {\n\talert(bar);\n});",
)();
foo(); // 関数本体の文字列で "function() {\n\talert(bar);\n}" の部分は再解析されません
```

関数宣言はとても簡単に (しばしば意図せずに) 関数式に変化します。関数宣言は以下のようなときには関数宣言ではなくなります。

* 式の一部になったとき
* 関数またはスクリプト自体の「ソース要素 (source element)」でなくなったとき。「ソース要素」はスクリプトや関数本体の中で入れ子にされていない文のことです。

```js
var x = 0; // ソース要素
if (x === 0) {
  // ソース要素
  x = 10; // ソース要素ではない
  function boo() {} // ソース要素ではない
}
function foo() {
  // ソース要素
  var y = 20; // ソース要素
  function bar() {} // ソース要素
  while (y === 10) {
    // ソース要素
    function blah() {} // ソース要素ではない
    y++; // ソース要素ではない
  }
}
```

### 例

```js
// 関数宣言
function foo() {}

// 関数式
(function bar() {});

// 関数式
x = function hello() {};

if (x) {
  // 関数式
  function world() {}
}

// 関数宣言
function a() {
  // 関数宣言
  function b() {}
  if (0) {
    // 関数式
    function c() {}
  }
}
```

ブロックレベル関数
---------

strict モードでは ES2015 から、ブロック内の関数はそのブロックに新しいスコープを形成します。 ES2015 より前では、ブロックレベル関数は strict モードでは禁止されています。

```js
"use strict";

function f() {
  return 1;
}

{
  function f() {
    return 2;
  }
}

f() === 1; // true

// strict モード以外では f() === 2
```

### strict コード以外におけるブロックレベル関数

一言で言えば、使わないでください。

strict コード以外では、ブロック内の関数宣言は奇妙な動作をします。次の例を見てください。

```js
if (shouldDefineZero) {
  function zero() {
    // 危険: 互換性リスク
    console.log("This is zero.");
  }
}
```

ES2015 では `shouldDefineZero` が false の場合、このブロックが実行されることはないので、`zero` は決して定義されないとされています。しかし、これは標準において新しいパーツです。歴史的には、このことは仕様とならないまま残されていました。いくつかのブラウザーでは、ブロックが実行されてもされなくても、`zero` を定義したでしょう。

strict モードでは、ES2015 に対応するブラウザーはすべて、これを同じように扱います。 `zero` は `shouldDefineZero` が true の場合のみ定義され、かつ `if` ブロックのスコープに限られます。

条件付きで関数を定義するより安全な方法は、変数に関数式を代入することです。

```js
var zero;
if (shouldDefineZero) {
  zero = function () {
    console.log("This is zero.");
  };
}
```

例
-

### 整形された数値を返す

次の関数は、数値の先頭にゼロを足して固定長にした形で表される文字列を返します。

```js
// この関数は先頭にゼロを足して固定長にした文字列を返す
function padZeros(num, totalLen) {
  var numStr = num.toString(); // 戻り値を文字列に初期化する
  var numZeros = totalLen - numStr.length; // ゼロの数を計算する
  for (var i = 1; i <= numZeros; i++) {
    numStr = "0" + numStr;
  }
  return numStr;
}
```

次の文で padZeros 関数を呼び出します。

```js
var result;
result = padZeros(42, 4); // "0042" を返す
result = padZeros(42, 2); // "42" を返す
result = padZeros(5, 4); // "0005" を返す
```

### 関数が存在するかどうか確認する

`typeof` 演算子を使うと関数が存在するかどうかを確かめることができます。次の例では、`window` オブジェクトが `noFunc` という関数のプロパティを持つかどうかを確かめるためのテストが行われます。もし持っていたら、それが使われます。そうでなければ、他の行動が取られます。

```js
if ("function" === typeof window.noFunc) {
  // noFunc() を使う
} else {
  // 何か他のことをする
}
```

`if` のテストの中で、`noFunc` への参照が使われているのに注目してください。関数名の後に括弧 "()" がないので、実際の関数は呼び出されません。

仕様書
---

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

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

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

関連情報
----

* `function 文`
* `function 式`
* `function* 文`
* `function* 式`
* `Function`
* `ジェネレーター関数`
* `アロー関数`
* `デフォルト引数`
* `残余引数`
* `arguments オブジェクト`
* `ゲッター`
* `セッター`
* `メソッド定義`


末尾のカンマ - JavaScript

末尾のカンマ
======

**末尾のカンマ** (「最後のカンマ」と呼ばれることもあります) は、JavaScript のコードに新しい要素や引数、プロパティを追加するときに役立ちます。新しいプロパティを追加するとき、最終行ですでに末尾のカンマを使用していれば、最終行を修正することなく新しい行を追加できます。これによって、バージョン管理の差分がより洗練され、コード編集の煩雑さを軽減できます。

JavaScript は、当初から配列リテラルで末尾のカンマを使用できました。その後でオブジェクトリテラルで、さらに最近では、関数の引数の末尾のカンマが使用できるようになりました。

しかし、JSON では末尾のカンマを許容していません。

構文
--

```js
,
```

例
-

### リテラルの末尾のカンマ

#### 配列

JavaScript は配列の末尾のカンマを無視します。

```js
var arr = [1, 2, 3];

arr; // [1, 2, 3]
arr.length; // 3
```

2 つ以上の末尾のカンマがある場合、省略 (または穴) が作られます。穴がある配列は*疎らな*配列と呼ばれます (*密集した*配列は穴がありません)。たとえば、`Array.prototype.forEach()` や `Array.prototype.map()` で配列を反復処理するとき、穴はスキップされます。

```js
var arr = [1, 2, 3, , ,];
arr.length; // 5
```

#### オブジェクト

ECMAScript 5 から、オブジェクトリテラルでも末尾のカンマを使用できるようになりました。

```js
var object = {
  foo: "bar",
  baz: "qwerty",
  age: 42,
};
```

### 関数の末尾のカンマ

ECMAScript 2017 では、関数の引数リストで末尾のカンマが使用できるようになりました。

#### 引数定義

次の 2 つの関数定義はともに有効で等しいものです。末尾のカンマは、関数の `length` プロパティや `arguments` オブジェクトに影響を与えません。

```js
function f(p) {}
function f(p,) {}

(p) => {};
(p,) => {};
```

末尾のカンマは、クラスやオブジェクトのメソッド定義でも使用できます。

```js
class C {
  one(a,) {}
  two(a, b,) {}
}

var obj = {
  one(a,) {},
  two(a, b,) {},
};
```

#### 関数呼び出し

次の 2 つの関数呼び出しはともに有効で等しいものです。

```js
f(p);
f(p,);

Math.max(10, 20);
Math.max(10, 20,);
```

#### 不正な末尾のカンマ

関数の定義や呼び出しにおいて引数がカンマしかないと、`SyntaxError` が発生します。さらに、残余引数を使用しているときは、末尾のカンマは許可されません。

```js
function f(,) {} // SyntaxError: missing formal parameter
(,) => {};       // SyntaxError: expected expression, got ','
f(,)             // SyntaxError: expected expression, got ','

function f(...p,) {} // SyntaxError: parameter after rest parameter
(...p,) => {}        // SyntaxError: expected closing parenthesis, got ','
```

### 分割代入での末尾のカンマ

末尾のカンマは、分割代入の左辺でも使用できます。

```js
// 末尾のカンマ付きで配列を分割代入
[a, b,] = [1, 2];

// 末尾のカンマ付きでオブジェクトを分割代入
var o = {
  p: 42,
  q: true,
};
var {p, q,} = o;
```

また、残余要素で使用すると、`SyntaxError` が発生します。

```js
var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma
```

### JSON の末尾のカンマ

オブジェクトリテラルの末尾のカンマは、ECMAScript 5 から導入されました。JSON は ES5 以前の JavaScript 構文に基づいているため、**末尾のカンマを使用できません**。

どちらの行も `SyntaxError` が発生します。

```js
JSON.parse("[1, 2, 3, 4, ]");
JSON.parse('{"foo" : 1, }');
// SyntaxError JSON.parse: unexpected character
// at line 1 column 14 of the JSON data
```

正しく JSON を解釈するには、カンマを省略してください。

```js
JSON.parse("[1, 2, 3, 4 ]");
JSON.parse('{"foo" : 1 }');
```

### 名前付きインポートおよび名前付きエクスポートの末尾のカンマ

末尾のカンマは名前付きインポートや名前付きエクスポートでも有効です。

#### 名前付きインポート

```js
import { A, B, C } from "D";

import { X, Y, Z } from "W";

import { A as B, C as D, E as F } from "Z"; // インポートの名前を変更
```

#### 名前付きエクスポート

```js
export { A, B, C };

export { A, B, C };

export { A as B, C as D, E as F }; // エクスポートの名前を変更
```

### 数量接頭辞

```js
  //{ DecimalDigits[~Sep], DecimalDigits[~Sep] }
  x{n,}
  x{n,m}
  x{n,m}?
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-Elision |
| ECMAScript Language Specification # prod-ObjectLiteral |
| ECMAScript Language Specification # prod-ArrayLiteral |
| ECMAScript Language Specification # prod-Arguments |
| ECMAScript Language Specification # prod-FormalParameters |
| ECMAScript Language Specification # prod-CoverParenthesizedExpressionAndArrowParameterList |
| ECMAScript Language Specification # prod-NamedImports |
| ECMAScript Language Specification # prod-NamedExports |
| ECMAScript Language Specification # prod-QuantifierPrefix |
| ECMAScript Language Specification # prod-annexB-InvalidBracedQuantifier |

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

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

関連情報
----

* 初期の ECMAScript の提案: trailing function commas by Jeff Morrison


標準組み込みオブジェクト - JavaScript

標準組み込みオブジェクト
============

本章では JavaScript の標準組み込みオブジェクトについて、それらのメソッドやプロパティと共にすべて文書化しています。

ここでいう「グローバルオブジェクト (global objects)」 (または標準組み込みオブジェクト) という用語を**グローバルオブジェクト** (the global object) と混同しないでください。ここで、『グローバルオブジェクト』は**グローバルスコープにあるオブジェクト**を指します。 (訳注: 日本語では複数形や the による区別ができないため、ここでは後者の **the global object** を『グローバルオブジェクト』と表記して区別します。)

後者の『グローバルオブジェクト』自体は、グローバルスコープ中で `this` 演算子を使ってアクセスすることができます。実際、グローバルスコープは『グローバルオブジェクト』のプロパティと、もしあれば継承されたプロパティから**構成されています**。

グローバルスコープ内のその他のオブジェクトは、ユーザースクリプトによって作られたり、ホストアプリケーションによって提供されたりします。ブラウザー上で提供されている利用可能なオブジェクトについては、API リファレンスで文書化されています。

DOM と中核の JavaScript との違いについての詳しい情報は、JavaScript 技術概説をご覧ください。

標準オブジェクト (カテゴリー別)
-----------------

### 値プロパティ

これらのグローバルプロパティは、単なる値を返します。プロパティもメソッドも持ちません。

* `Infinity`
* `NaN`
* `undefined`
* `globalThis`
### 関数プロパティ

これらのグローバル関数 (オブジェクト上ではなくグローバルに呼ばれる関数) は、呼び出し元に直接結果を返します。

* `eval()`
* Non-standard
 `uneval()`
* `isFinite()`
* `isNaN()`
* `parseFloat()`
* `parseInt()`
* `encodeURI()`
* `encodeURIComponent()`
* `decodeURI()`
* `decodeURIComponent()`
* **非推奨**
    + 非推奨
     `escape()`
    + 非推奨
     `unescape()`
### 基本オブジェクト

他のすべてのオブジェクトの基礎となる、主要な基本オブジェクトです。一般的なオブジェクト、関数、そしてエラーを表すオブジェクトが含まれます。

* `Object`
* `Function`
* `Boolean`
* `Symbol`
### エラーオブジェクト

エラーオブジェクトは基本オブジェクトの特殊型です。これらのオブジェクトには、基本的な `Error` 型の他に、いくつかの特殊なエラー型があります。

* `Error`
* `AggregateError`
* `EvalError`
* `InternalError`
* `RangeError`
* `ReferenceError`
* `SyntaxError`
* `TypeError`
* `URIError`
### 数値と日付

数値、日付、数学計算を表す基本的なオブジェクトです。

* `Number`
* `BigInt`
* `Math`
* `Date`
### テキスト処理

これらのオブジェクトは、文字列を表したりその操作をサポートしたりします。

* `String`
* `RegExp`
### 索引付きコレクション

これらのオブジェクトは、インデックス値で順序付けされたデータのコレクションを表します。これには、(型付けされた) 配列や配列に似た構造体も含まれます。

* `Array`
* `Int8Array`
* `Uint8Array`
* `Uint8ClampedArray`
* `Int16Array`
* `Uint16Array`
* `Int32Array`
* `Uint32Array`
* `Float32Array`
* `Float64Array`
* `BigInt64Array`
* `BigUint64Array`
### キー付きコレクション

これらのオブジェクトは、キーを使ったコレクションを表します。反復可能なコレクション (`Map` と `Set`) は挿入順に容易に反復処理することができます。

* `Map`
* `Set`
* `WeakMap`
* `WeakSet`
### 構造化データ

これらのオブジェクトは、構造化データバッファおよび JavaScript Object Notation (JSON) を用いて書かれたデータを表現、操作します。

* `ArrayBuffer`
* `SharedArrayBuffer`
* `Atomics`
* `DataView`
* `JSON`
### 制御抽象化オブジェクト

制御抽象化オブジェクトは、特に非同期のコードを (例えば深く入り組んだコールバックを使用せずに) 構造化するのに役立ちます。

* `Promise`
* `Generator`
* `GeneratorFunction`
* `AsyncFunction`
* `AsyncGenerator`
* `AsyncGeneratorFunction`
### リフレクション

* `Reflect`
* `Proxy`
### 国際化

中核の ECMAScript に言語に固有の機能を追加するものです。

* `Intl`
* `Intl.Collator`
* `Intl.DateTimeFormat`
* `Intl.ListFormat`
* `Intl.NumberFormat`
* `Intl.PluralRules`
* `Intl.RelativeTimeFormat`
* `Intl.Locale`
### WebAssembly

* `WebAssembly`
* `WebAssembly.Module`
* `WebAssembly.Instance`
* `WebAssembly.Memory`
* `WebAssembly.Table`
* `WebAssembly.CompileError`
* `WebAssembly.LinkError`
* `WebAssembly.RuntimeError`
### その他

* `arguments`


正規表現 - JavaScript

正規表現
====

**正規表現**（略して *regex*）は、開発者が文字列をパターンと照合したり、部分一致情報を抽出したり、単に文字列がそのパターンに適合するかどうかを検査したりすることができます。正規表現は多くのプログラミング言語で使われており、JavaScript の構文は Perl から影響を受けています。

利用できる正規表現の構文とこれらがどのように動作するのかの概要を把握するために、正規表現ガイドを読むことをお勧めします。

解説
--

正規表現は、形式言語理論における重要な概念です。正規表現は、文字列の無限集合（「言語」と呼ばれる）を記述する方法です。正規表現の核となるのは以下の機能です：

* その言語で使用できる「文字」の集合。これは「アルファベット」と呼ばれます。
* 連結: `ab` は「文字 `a` に続く文字 `b`」を意味しています。
* 論理和: `a|b` は「`a` か `b` のどちらか」を意味しています。
* クリーネスター: `a*` は「0文字以上の `a` 文字」を意味しています。

有限のアルファベット（英語のアルファベット 26 文字や Unicode 文字集合全体など）とみなされると、すべての正規言語は上記の機能によって生成することができます。もちろん、多くのパターンはこの方法で表現するのはとても面倒なので (「10 桁の数字」や「空白文字ではない文字」など)、JavaScript の正規表現には下記に紹介するような多くの略記法が含まれています。

**メモ:** JavaScriptの正規表現は後方参照が存在するため、実際には正規表現ではありません（正規表現は有限状態を持つ必要があります）。しかし、それでもとても有益な機能です。

### 正規表現の作成

正規表現は通常、パターンをスラッシュ (`/`) で囲んでリテラルとして作成します。

```js
const regex1 = /ab+c/g;
```

正規表現は `RegExp()` コンストラクターで作成することもできます。

```js
const regex2 = new RegExp("ab+c", "g");
```

実行時の違いはありませんが、パフォーマンス、静的解析性、およびエスケープ文字のオーサリングの人間工学的な課題に影響を持つことができます。詳しい情報は `RegExp` を参照してください。

### 正規表現フラグ

フラグは、正規表現が解釈される方法や入力テキストとやりとりする方法を変更できる特別な引数です。各フラグは `RegExp`` オブジェクトの 1 つのアクセサープロパティに対応します。

| フラグ | 説明 | 対応するうプロパティ |
| --- | --- | --- |
| `d` | 部分文字列の一致のインデックスを生成します。 | `hasIndices` |
| `g` | グローバル検索です | `global` |
| `i` | 大文字小文字を区別しない検索です。 | `ignoreCase` |
| `m` | 改行文字を `^` および `$` と一致させます。 | `multiline` |
| `s` | `.` を改行文字と一致させます。 | `dotAll` |
| `u` | "Unicode" です。パターンを Unicode コードポイントの並びとして扱います。 | `unicode` |
| `v` | `u` モードをアップグレードし、もっと多くの Unicode 機能を使用可能にします。 | `unicodeSets` |
| `y` | 対象とする文字列の現在位置から始めて一致する「粘着」(sticky) 検索を行います。 | `sticky` |

以下の一覧は、利用できるすべての正規表現構文を、構文の性質ごとに分類したものです。

### アサーション

アサーションは、文字列が指定した位置で特定の条件を満たすかどうかを検査する構文です。アサーションは数量化できません。

入力境界アサーション: `^`, `$`

現在の位置が入力の開始または終了であること、または `m` フラグが設定されている場合は、行の開始または終了であることを表します。

先読みアサーション: `(?=...)`, `(?!...)`

現在の位置が特定のパターンの後に来ること、または来ないことを表します。

後読みアサーション: `(?<=...)`, `(?<!...)`

現在の位置が特定のパターンの前に来ること、または来ないことを表します。

単語境界アサーション: `\b`, `\B`

現在の位置が単語境界であることを表します。

### アトム

アトムは正規表現の最も基本的な単位です。各アトムは文字列中の 1 つ以上の文字を「消費」し、照合に失敗するか、次のアトムでパターンの照合を続けかのどちらかです。

後方参照: `\1`, `\2`

その前でキャプチャグループに一致し、捕捉されたサブパターンに一致します。

キャプチャグループ: `(...)`

サブパターンに一致し、一致した情報を記憶します。

文字クラス: `[...]`, `[^...]`

ある文字集合に含まれる、または含まれない文字と一致します。`v` フラグを有効にすると、可変長の文字列にも一致するように使用することができます。

文字クラスエスケープ: `\d`, `\D`, `\w`, `\W`, `\s`, `\S`

あらかじめ設定された文字集合に含まれる、または含まれない文字と一致します。

文字エスケープ: `\n`, `\u{...}`

リテラル形式では表現しにくい文字と一致します。

リテラル文字: `a`, `b`

特定の文字と一致します。

名前付き後方参照: `\k<name>`

その前で名前付きキャプチャグループに一致し、捕捉されたサブパターンに一致します。

名前付きキャプチャグループ: `(?<name>...)`

サブパターンに一致し、一致した情報を記憶します。このグループは、パターン内のインデックスではなく、独自の名前で識別することができます。

非キャプチャグループ: `(?:...)`

一致した情報を記憶することなく、サブパターンに一致します。

Unicode 文字クラスエスケープ: `\p{...}`, `\P{...}`

Unicode プロパティを指定します。`v` フラグを有効にすると、可変長の文字列にも一致するように使用することができます。

ワイルドカード: `.`

`s` フラグが設定されていない限り、改行以外の文字と一致します。

### その他の機能

これらの機能はそれ自身はパターンを指定しませんが、パターンを構成するために使用します。

論理和: `|`

`|` 文字で区切られた選択肢の集合のいずれかと一致します。

修飾子: `*`, `+`, `?`, `{n}`, `{n,}`, `{n,m}`

アトムに一定回数一致します。

### エスケープシーケンス

正規表現における「エスケープシーケンス」とは、`\` の後に 1 つ以上の文字が続くことで形成される構文のことを指します。以下は有効なエスケープシーケンスの一覧です。

| エスケープシーケンス | 続くもの | 意味 |
| --- | --- | --- |
| `\B` | なし | 非単語境界アサーション |
| `\D` | なし | 文字クラスエスケープで、数字以外の文字を表す |
| `\P` | `{`、Unicode プロパティや値、`}` | Unicode 文字クラスエスケープで、指定された Unicode プロパティ以外の文字を表す |
| `\S` | なし | 文字クラスエスケープで、ホワイトスペース文字以外を表す |
| `\W` | なし | 文字クラスエスケープで、言語文字以外を表す |
| `\b` | なし | 単語境界アサーション。文字クラスの中では U+0008 (BACKSPACE) を表す |
| `\c` | `A` から `Z` または `a` から `z` | 文字エスケープで、値がその文字の 32 で割った余りとなる制御文字表す |
| `\d` | なし | 文字クラスエスケープで、数字（`0` から `9`）を表す |
| `\f` | なし | 文字エスケープで、 U+000C (FORM FEED) を表す |
| `\k` | `<`、識別子、`>` | 名前付き後方参照 |
| `\n` | なし | 文字エスケープで、U+000A (LINE FEED) を表す |
| `\p` | `{`、Unicode プロパティや値、`}` | Unicode 文字クラスエスケープで、指定された Unicode プロパティの文字を表す |
| `\q` | `{`、文字列、`}` | `v` モードの文字クラスのみで有効。文字通り一致させる文字列を表す |
| `\r` | なし | 文字エスケープで、U+000D (CARRIAGE RETURN) を表す |
| `\s` | なし | 文字クラスエスケープで、ホワイトスペース文字を表す |
| `\t` | なし | 文字エスケープで、U+0009 (CHARACTER TABULATION) を表す |
| `\u` | 4 桁の 16 進数、または `{`、1 ～ 6 桁の 16 進数、`}` | 文字エスケープで、指定されたコードポイントの文字を表す |
| `\v` | なし | 文字エスケープで、U+000B (LINE TABULATION) を表す |
| `\w` | なし | 文字クラスエスケープで、言語文字を（`A` ～ `Z`, `a` ～ `z`, `0` ～ `9`, `_`）を表す |
| `\x` | 2 桁の 16 進数 | 文字エスケープで、指定された値の文字を表す |
| `\0` | なし | 文字エスケープで、U+0000 (NULL) を表す |

`\` \ に他の数字が続くと古い 8 進数のエスケープシーケンスになり、Unicode 対応モードでは禁止されています。

加えて、`\` には一部の記号や数字を続けることができ、この場合、エスケープシーケンスは常にエスケープされる文字自身を表す文字エスケープとなります。

* `\$`, `\(`, `\)`, `\*`, `\+`, `\.`, `\/`, `\?`, `\[`, `\\`, `\]`, `\^`, `{`, `\|`, `}`: valid everywhere
* `\-`: 文字クラスの中でのみ有効
* `\!`, `\#`, `\%`, `\&`, `\,`, `\:`, `\;`, `\<`, `\=`, `\>`, `\@`, `\``, `\~`: `v` モード文字クラスの中でのみ有効

他にも ASCII 文字、すなわち空白文字、`"`、`'`、`_`、そして上記以外の文字は有効なエスケープシーケンスではありません。Unicode 非対応モードでは、上記のいずれでもないエスケープシーケンスは識別エスケープとなり、バックスラッシュに続く文字を表します。例えば、`\a` は文字 `a` を表します。この動作は、後方互換性の課題を発生させることなく新しいエスケープシーケンスを導入する能力を制限するため、Unicode 対応モードでは禁止されています。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-DecimalEscape |
| ECMAScript Language Specification # prod-Atom |
| ECMAScript Language Specification # prod-CharacterClass |
| ECMAScript Language Specification # prod-CharacterClassEscape |
| ECMAScript Language Specification # prod-CharacterEscape |
| ECMAScript Language Specification # prod-Disjunction |
| ECMAScript Language Specification # prod-Assertion |
| ECMAScript Language Specification # prod-PatternCharacter |
| ECMAScript Language Specification # prod-AtomEscape |
| ECMAScript Language Specification # prod-Quantifier |

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

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

関連情報
----

* 正規表現ガイド
* `RegExp`


字句文法 - JavaScript

字句文法
====

このページでは、 JavaScript での字句文法を説明します。JavaScript のソーステキストは、単なる文字の列です。これをインタープリターに理解させるためには、文字列をより構造化された表現に解釈させる必要があります。構文解析の最初の手順は字句解析と呼ばれ、テキストを左から右へスキャンして、個々の原子的な入力要素の列に変換します。一部の入力要素はインタープリターにとって重要ではないので、この手順の後で取り除かれます。制御文字、行の終端文字、ホワイトスペース、コメントがそれに該当します。識別子や句読点などの他にも、更なる構文解析のために使用されます。 ECMAScript はまた、特定のキーワードとリテラルを定義し、特定の無効なトークン列を有効にするためにセミコロンを自動的に挿入する規則を持っています。

書式化制御文字
-------

書式化制御文字は、視覚的表現を有していないものの、テキストの解釈を制御するために使用されます。

| コードポイント | 名前 | 略語 | 説明 |
| --- | --- | --- | --- |
| U+200C | Zero width non-joiner | <ZWNJ> | 特定の言語において、合字に接合されることを防ぐために、文字の間に配置されます。(Wikipedia) |
| U+200D | Zero width joiner | <ZWJ> | 特定の言語において、通常は接合されない文字を、接合した形を使用して文字を表示するために文字間に配置されます。 (Wikipedia) |
| U+FEFF | Byte order mark | <BOM> | 記述の先頭において、 Unicode を使用することと、そのテキストのバイト順をマークします。 (Wikipedia). |

JavaScriptのソーステキストでは、 <ZWNJ> と <ZWJ> は識別子部分として扱われ、 <BOM> （テキストの先頭にない場合はゼロ幅のノーブレークスペース <ZWNBSP> とも呼ばれます）は空白部分として扱われます。

ホワイトスペース
--------

ホワイトスペースはソースのテキストの読みやすさを向上させ、トークンを互いに区別します。これらの文字は通常、コードの機能性には不要なものです。よく Minification tools を使用して、転送する必要があるデータの量を削減するためにホワイトスペースを除去します。

| コードポイント | 名前 | 略語 | 説明 | エスケープシーケンス |
| --- | --- | --- | --- | --- |
| U+0009 | 文字単位のタブ | <TAB> | 水平タブ | \t |
| U+000B | 行単位のタブ | <VT> | 垂直タブ | \v |
| U+000C | フォームフィード | <FF> | 改ページの制御文字 (Wikipedia) | \f |
| U+0020 | 空白 | <SP> | 通常の空白 |  |
| U+00A0 | ノーブレークスペース | <NBSP> | 通常の空白だが、改行を行ってよい位置ではない |  |
| U+FEFF | ゼロ幅ノーブレークスペース | <ZWNBSP> | When not at the start of a script, the BOM marker is a normal whitespace character. |  |
| Others | 他の Unicode の空白文字 | <USP> | "Space\_Separator" 一般カテゴリーの文字 |  |

**メモ:** "White\_Space" プロパティがあるが "Space\_Separator" 一般カテゴリーにない文字のうち、 U+0009, U+000B, U+000C は JavaScript でもホワイトスペースとして扱われ、 U+0085 NEXT LINE は特別な役割を持たず、他にも改行文字の集合となるものがあります。

**メモ:** JavaScript エンジンで使用される Unicode 規格が変更されると、プログラムの動作に影響を与える可能性があります。例えば、 ES2016 では参照する Unicode 規格が 5.1 から 8.0.0 にアップグレードされ、その影響で U+180E MONGOLIAN VOWEL SEPARATOR が "Space\_Separator" カテゴリから「書式化（Cf）」カテゴリに移動し、空白でなくなっています。その結果、" \u180E".trim().length の結果が 0 から 1 に変更されました。

改行文字
----

ホワイトスペース文字に加えて、改行文字もソースのテキストの読みやすさを改善するために使用されます。しかし、改行文字は JavaScript の実行に影響を与える場合があり、禁止されている場所もいくらかあります。改行文字は自動セミコロン挿入の処理にも影響を与えます。改行文字は正規表現の `\s` クラスに一致します。

以下の Unicode コードポイントのみが ECMAScript では改行文字として扱われ、他の改行文字はホワイトスペースとして扱われます (例えば、次の行、 NEL、 U+0085 はホワイトスペースと見なされます)。

| コードポイント | 名前 | 略語 | 説明 | エスケープシーケンス |
| --- | --- | --- | --- | --- |
| U+000A | ラインフィード | <LF> | UNIX システムでの改行文字です。 | \n |
| U+000D | キャリッジリターン | <CR> | コモドールと初期の Mac システムでの改行文字です。 | \r |
| U+2028 | ラインセパレーター | <LS> | ウィキペディア |  |
| U+2029 | 改段落 | <PS> | ウィキペディア |  |

コメント
----

コメントは、ヒント、メモ、提案、警告を JavaScript のコードに追加するために使用されます。これにより、コードがより読みやすく、より理解しやすいものなります。また、コードが実行されないよう無効にするために使用することができます。これは、貴重なデバッグツールになることがあります。

JavaScript には、コード内にコメントを割り当てる方法が 2 つあります。

### 行コメント

1 番目の方法は `//` コメントです。つまり、これは同じ行にある、その後のすべてのテキストをコメントにします。例えば、

```js
function comment() {
  // This is a one line JavaScript comment
  console.log("Hello world!");
}
comment();
```

### ブロックコメント

2 番目の方法は `/* */` スタイルで、もっとずっと柔軟なものです。

例えば、単一行に利用した場合は次のようになります。

```js
function comment() {
  /\* This is a one line JavaScript comment \*/
  console.log("Hello world!");
}
comment();
```

複数行のコメントも下記のように作成することができます。

```js
function comment() {
  /\* This comment spans multiple lines. Notice
 that we don't need to end the comment until we're done. \*/
  console.log("Hello world!");
}
comment();
```

必要であれば、行の途中でコメントを使用することもできますが、これはコードが読みにくくなることがあるので注意が必要です。

```js
function comment(x) {
  console.log("Hello " + x /\* insert the value of x \*/ + " !");
}
comment("world");
```

また、コードをコメントで囲むことで、コードが実行されないよう無効にすることができます。

```js
function comment() {
  /\* console.log('Hello world!'); \*/
}
comment();
```

この場合、 `console.log()` の呼び出しはコメント内部にあるので、実行されることはありません。何行分のコードであっても、このようにして無効にすることができます。

### ハッシュバンコメント

特別な 3 つ目のコメント構文として**ハッシュバンコメント**があります。ハッシュバンコメントは、 `#!` で始まることと、**スクリプトやモジュールの絶対的な開始位置でのみ有効であること**を除いて、単一の行のみ (`//`) のコメントと全く同じように動作します。なお、 `#!` の前にはいかなる種類の空白も許されないことにも注意してください。コメントは `#!` 以降の最初の行の終わりまでのすべての文字で構成され、このようなコメントは 1 つだけ許可されます。

JavaScriptでのハッシュバンコメントは Unix におけるシバンに似ていて、スクリプトを実行するために使用したい特定の JavaScript インタープリターへのパスを指定します。ハッシュバンコメントが標準化される前に、 Node.js のようなブラウザー以外のホストではすでにデファクトとして実装されており、エンジンに渡される前にソーステキストから取り除かれるようになっていました。例として以下のようなものがあります。

```js
#!/usr/bin/env node

console.log("Hello world");
```

JavaScript インタープリターはこれを通常のコメントとして扱います。スクリプトが直接シェルで実行された場合のみ、シェルに対して意味を持ちます。

**警告:** スクリプトをシェル環境で直接実行できるようにしたい場合は、 BOM のない UTF-8 でエンコードしてください。ハッシュバンコメントの前に BOM があってもブラウザーでは動作しますが、ハッシュバンのあるスクリプトで BOM を使用することは推奨されていません。 BOM は Unix/Linux のシェル環境でスクリプトを実行しようとすると動作しません。したがって、シェル環境から直接スクリプトを実行したい場合は BOM のない UTF-8 を使用してください。

`#!` の形のコメントは JavaScript インタープリターを指定するためにだけ使用してください。他の用途ではすべて `//` のコメント（または複数行コメント）を使用してください。

識別子
---

*識別子* は、値と名前をリンクさせるために使用されます。識別子は様々な場所で使用することができます。

```js
const decl = 1; // 変数宣言（`let` または `var` も可）
function fn() {} // 関数宣言
const obj = { key: "value" }; // オブジェクトキー
class C {
  // クラス宣言
  #priv = "value"; // プライベートプロパティ
}
lbl: console.log(1); // ラベル
```

JavaScript では、識別子は一般的に英数字、アンダースコア (`_`)、ドル記号 (`$`) で構成されます。識別子は数字で始めることはできません。しかし、JavaScript で使用できる識別子は ASCII だけではなく、ほとんどの Unicode コードポイントも使用可能です。

**メモ:** もし何らかの理由で JavaScript のソースを自分で解析する必要がある場合、すべての識別子が `/[A-Za-z_$][\w$]*/` のパターンに従っている（つまり ASCII のみ）と仮定しないでください。 識別子の範囲は正規表現 `/[$_p{ID_Start}][$u200cu200dp{ID_Continue}]*/u` (Unicodeエスケープシーケンスを除く) で記述することができます。

また、JavaScript では、識別子の中で Unicode エスケープシーケンスを `\u0000` または `\u{000000}` という形式で使用することができ、これは実際の Unicode 文字と同じ文字列値をエンコードするものです。例えば、`你好` と `\u4f60\u597d` は同じ識別子です。

```js
const 你好 = "Hello";
console.log(\u4f60\u597d); // Hello
```

すべての場所で、すべての範囲の識別子が受け入れられるわけではありません。関数宣言、関数式、変数宣言などの特定の構文では、予約語でない識別子名を使用する必要があります。

```js
function import() {} // 違反: import は予約語です。
```

最も注目すべきは、プライベートプロパティとオブジェクトプロパティは、予約語を許可していることです。

```js
const obj = { import: "value" }; // `import` は予約語だが有効
class C {
  #import = "value";
}
```

キーワード
-----

*キーワード* は識別子のように見えますが、 JavaScript で特別な意味を持つトークンです。例えば、関数宣言の前のキーワード `async` は、その関数が非同期であることを示します。

キーワードの中には*予約*されているものがあり、変数宣言や関数宣言などの識別子として使用することができないことを意味します。これらはよく*予約語*と呼ばれます。予約語の一覧は下記に掲載されています。すべてのキーワードが予約されているわけではありません。例えば、 `async` はどこでも識別子として使用することができます。一部のキーワードは*文脈的な予約語*です。例えば、 `await` は非同期関数の本体でのみ、 `let` は厳格モードコード、または `const` および `let` 宣言でのみ予約されています。

識別子は常に *文字列値* で比較されるため、エスケープシーケンスは解釈されます。例えば、このような場合も構文エラーとなります。

```js
const els\u{65} = 1;
// `els\u{65}` encodes the same identifier as `else`
```

### 予約語

これらのキーワードは、 JavaScript で変数、関数、クラスなどの識別子として使用することはできません。

* `break`
* `case`
* `catch`
* `class`
* `const`
* `continue`
* `debugger`
* `default`
* `delete`
* `do`
* `else`
* `export`
* `extends`
* `false`
* `finally`
* `for`
* `function`
* `if`
* `import`
* `in`
* `instanceof`
* `new`
* `null`
* `return`
* `super`
* `switch`
* `this`
* `throw`
* `true`
* `try`
* `typeof`
* `var`
* `void`
* `while`
* `with`

以下のものは、厳格モードのコードで使われた場合のみ予約語になります。

* `let` （`const`、`let`、クラス定義でも予約語になる）
* `static`
* `yield` （ジェネレーター関数の本体でも予約語になる）

以下のものは、モジュールコードや非同期関数本体に現れた場合にのみ予約語になります。

* `await`
### 今後の予約語

以下のものは、 ECMAScript の仕様によって今後のキーワードとして予約されています。これらは現時点では特別な機能を持っていませんが、将来は持つ可能性があるので、識別子として使用することはできません。

以下のものは常に予約されています。

* `enum`

以下のものは、厳格モードで遭遇した場合のみ予約語になります。

* `implements`
* `interface`
* `package`
* `private`
* `protected`
* `public`

#### 旧仕様にあった今後の予約キーワード

以前の ECMAScript の仕様書 (ECMAScript 1 から 3 まで) では、以下のものが将来のキーワードとして予約されています。

* `abstract`
* `boolean`
* `byte`
* `char`
* `double`
* `final`
* `float`
* `goto`
* `int`
* `long`
* `native`
* `short`
* `synchronized`
* `throws`
* `transient`
* `volatile`
### 特別な意味を持つ識別子

一部の識別子は、キーワードでなくても、あるコンテキストで特別な意味を持つことがあります。それらは以下の通りです。

* `arguments` （キーワードではありませんが、厳格モードでは識別子として宣言できません）
* `as` (`import * as ns from "mod"`)
* `async`
* `eval` （キーワードではありませんが、厳格モードでは識別子として宣言できません）
* `from` (`import x from "mod"`)
* `get`
* `of`
* `set`
リテラル
----

### Null リテラル

詳細については `null` をご覧ください。

```js
null;
```

### 論理値リテラル

詳細については論理型をご覧ください。

```js
true;
false;
```

### 数値リテラル

数値型 (Number) および長整数型 (BigInt) が数値リテラルを使用します。

#### 10 進数

```js
1234567890;
42;

// 先頭にゼロがあるものを使用する場合は注意してください
0888; // 888 は 10 進数として解釈されます
0777; // 8 進数として解釈され、 10 進数では 511 です。
```

なお、 10 進数リテラルはゼロ (`0`) から始め、他の 10 進数の数字を続けることができますが、 `0` に続く数字がすべて 8 より小さい場合は、その数値が 8 進数として解釈されることに注意してください。さらに、接頭辞 `0` を持つ数値リテラルは、 8 進数として解釈しても 10 進数として解釈しても、厳格モードでは構文エラーが発生します。ですから、代わりに `0o` 接頭辞を使用してください。

##### 指数

10 進数の指数リテラルは、 `beN` の書式で指定します。ここで `b` は基数（整数または浮動小数点）、その後に `e` 文字（セパレーターまたは指数記号として機能）、そして `N` は*指数*または*べき乗数* - 符号付き整数です（2019 ECMA-262 仕様に従います）。

```js
0e-5; // 0
0e5; // 0
5e1; // 50
175e-2; // 1.75
1e3; // 1000
1e-3; // 0.001
1e3; // 1000
```

#### 2 進数

2進数の構文は、先頭のゼロに続いて小文字または大文字のラテン文字 "B" を使用します (`0b` または `0B`)。 `0b` の後の数字が 0 または 1 でない場合は、 `SyntaxError` が "Missing binary digits after 0b" の内容で発生します。

```js
const FLT\_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648
const FLT\_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
const FLT\_MANTISSA = 0b00000000011111111111111111111111; // 8388607
```

#### 8 進数

8進数の構文は、先頭のゼロに続いて小文字または大文字のラテン文字 "O" を使用します (`0o` または `0O`)。 `0o` の後の数字が範囲 (01234567) 外の場合、 `SyntaxError` が "Missing octal digits after 0o" の内容で発生します。

```js
const n = 0o755; // 493
const m = 0o644; // 420
```

#### 16 進数

16 進数の構文は、先頭のゼロに続いて小文字または大文字のラテン文字 "X" を使用します (`0x` または `0X`)。 0x の後の数字が範囲 (0123456789ABCDEF) 外の場合、 `SyntaxError` が "Identifier starts immediately after numeric literal" の内容で発生します。

```js
0xfffffffffffffffff; // 295147905179352830000
0x123456789abcdef; // 81985529216486900
0xa; // 10
```

#### 長整数リテラル

長整数型 (BigInt) は JavaScript の数値プリミティブであり、自由な精度の整数を表すことができます。長整数リテラルは、整数の末尾に `n` を追加することで作成されます。

```js
123456789123456789n; // 123456789123456789
0o777777777777n; // 68719476735
0x123456789abcdefn; // 81985529216486895
0b11101001010101010101n; // 955733
```

なお、先頭がゼロだけの 8 進数は `BigInt` では動作しません。

```js
0755n
// SyntaxError: invalid BigInt syntax
```

8 進数の `BigInt` 数値では、常にゼロの後に "o" (大文字でも小文字でも) を付けて使用してください。

```js
0o755n;
```

`BigInt` についての詳細な情報は、 JavaScript のデータ構造をご覧ください。

#### 数値の区切り文字

数値リテラルの可読性を高めるために、アンダースコア (`_`, `U+005F`) を区切り文字として使用することができます。

```js
// 10 進数の区切り文字
1\_000\_000\_000\_000;
1\_050.95;

// 2 進数の区切り文字
0b1010\_0001\_1000\_0101;

// 8 進数の区切り文字
0o2\_2\_5\_6;

// 16 進数の区切り文字
0xa0\_b0\_c0;

// BigInt の区切り文字
1\_000\_000\_000\_000\_000\_000\_000n;
```

なお、以下の制限があります。

```js
// 連続して 2 つ以上のアンダースコアは許可されていません
100__000; // SyntaxError

// 数値リテラルの末尾に置くことは許可されていません
100_; // SyntaxError

// 先頭の 0 の後に使用することはできません
0\_1; // SyntaxError
```

### オブジェクトリテラル

詳細については、 `Object` とオブジェクト初期化子をご覧ください。

```js
const o = { a: "foo", b: "bar", c: 42 };

// 短縮記法
const a = "foo",
  b = "bar",
  c = 42;
const o = { a, b, c };

// 以前の表記
const o = { a: a, b: b, c: c };
```

### 配列リテラル

詳細については `Array` をご覧ください。

```js
[1954, 1974, 1990, 2014];
```

### 文字列リテラル

文字列リテラルは、単一引用符または二重引用符に囲まれた零個以上の Unicode コードポイントです。 Unicode コードポイントはエスケープシーケンスで表すこともできます。以下の引用符を閉じるコードポイントを除いて、すべてのコードポイントが文字列リテラルに現れることができます。

* U+005C \ (バックスラッシュ)
* U+000D <CR>,
* and U+000A <LF>.

すべてのコードポイントが、エスケープシーケンスの形で現れることができます。文字列リテラルは ECMAScript の文字列値として評価されます。これらの文字列の値を生成する際に、 Unicode コードポイントは UTF-16 エンコードされます。

```js
'foo';
"bar";
```

#### 16 進エスケープシーケンス

16 進エスケープシーケンスは `\x` に続いてちょうど 2 桁の 16 進数から成り、 0x0000 から 0x00FF までのコード単位またはコードポイントを表します。

```js
"\xA9"; // "©"
```

#### Unicode エスケープシーケンス

Unicode エスケープシーケンスは `\u` に続いてちょうど 4 桁の 16 進数から成ります。これで UTF-16 エンコーディングのコード単位を表します。コードポイント U+0000 から U+FFFF までは、コード単位とコードポイントは等しくなります。コードポイント U+10000 から U+10FFFF までは、 2 つのエスケープシーケンスで 2 つのコード単位 (サロゲートペア) を表す必要があります。サロゲートペアはコードポイントで区別されます。

See also `String.fromCharCode()` and `String.prototype.charCodeAt()`.

```js
"\u00A9"; // "©" (U+A9)
```

#### Unicode コードポイントエスケープ

Unicode コードポイントエスケープは `\u{` に続いて 16 進数のコードポイントが続き、 `}` が続きます。 16 進数の値は 0 から 0x10FFFF までの範囲に含まれている必要があります。 U+10000 から U+10FFFF までの範囲のコードポイントを、サロゲートペアとして表す必要はありません。

`String.fromCodePoint()` または `String.prototype.codePointAt()` もご覧ください。

```js
"\u{2F804}"; // CJK COMPATIBILITY IDEOGRAPH-2F804 (U+2F804)

// 同じ文字をサロゲートペアで表したもの
"\uD87E\uDC04";
```

### 正規表現リテラル

詳細については `RegExp` を参照してください。

```js
/ab+c/g;

// 「空の」正規表現リテラル
// 単一行コメントと区別するために、空のキャプチャしない
// グループが必要です。
/(?:)/;
```

### テンプレートリテラル

詳細について、テンプレート文字列をご覧ください。

```js
`string text`;

`string text line 1
 string text line 2`;

`string text ${expression} string text`;

tag`string text ${expression} string text`;
```

自動セミコロン挿入
---------

一部の JavaScript 文はセミコロンで終わる必要があります。したがって、自動セミコロン挿入 (ASI) の影響を受けます。

* `let`, `const`, 変数定義
* `import`, `export`, モジュール宣言
* 式の文
* `debugger`
* `continue`, `break`, `throw`
* `return`

セミコロンが自動的に挿入されるケースは 3 つあります。

1. 文法上許されないトークンに出会ったとき、それが前のトークンから少なくとも 1 つの改行文字で区切られているか、そのトークンが "}" であれば、その前にセミコロンが挿入されます。

```js
{ 1
2 } 3

// 上記の文は、 ASI によって次のように変換されます

{ 1
;2 ;} 3;

// 3 つの文をエンコードする正しい文法で、
// それぞれが数値リテラルで構成されています
```

`do...while` の末尾の ")" は、このルールでも特別なケースとして扱われます。

```js
do {
  // ...
} while (condition); /\* ; \*/ // ここで ASI
const a = 1;
```

2. トークンの入力ストリームの末尾が検出され、パーサーが単一の入力ストリームを完全なプログラムとして解釈できない場合、末尾にセミコロンが挿入されます。

```js
const a = 1; /\* ; \*/ // ASI here
```

このルールは前回のルールを補完するもので、特に「問題のあるトークン」がなく、入力ストリームが終わっている場合を想定しています。

3. 文法上で改行が禁止されている場所で改行が見つかった場合は、セミコロンを挿入します。このような場所は、以下の通りです。

* `式 <ここ> ++`, `式 <ここ> --`
* `continue <ここ> ラベル`
* `break <ここ> ラベル`
* `return <ここ> 式`
* `throw <ここ> 式`
* `yield <ここ> 式`
* `yield <ここ> * 式`
* `(param) <ここ> => {}`
* `async <ここ> function`, `async <ここ> prop()`, `async <ここ> function*`, `async <ここ> *prop()`, `async <ここ> (param) <ここ> => {}`

ここで `++` は、変数 `b` に適用される後置演算子としては扱われません。というのも、改行文字が `b` と`++` の間にあるからです。

```js
a = b
++c

// 上記の文は、 ASI によって次のように変換されます

a = b;
++c;
```

ここでは、 `return` 文は `undefined` を返し、 `a + b` は到達できない文になります。

```js
return
a + b

// 上記の文は、 ASI によって次のように変換されます

return;
a + b;
```

ASI は、改行がなければ無効な構文を生成するようなトークンを区切った場合にのみ発生することに注意してください。次のトークンが有効な構文の一部として解釈できる場合は、セミコロンは挿入されません。例えば、

```js
const a = 1
(1).toString()

const b = 1
[1, 2, 3].forEach(console.log)
```

`()` は関数呼び出しと見なせるので、通常は ASI が発生しないでしょう。同様に、 `[]` はメンバーアクセスである可能性があります。上のコードは次のものと同等です。

```js
const a = 1(1).toString()

const b = 1[1, 2, 3].forEach(console.log)
```

そのため、コードを実行すると "1 is not a function" や "Cannot read properties of undefined (reading 'forEach')" などのエラーが発生することになります。

クラス内では、クラスフィールドやジェネレーターメソッドも落とし穴になることがあります。

```js
class A {
  a = 1
  \*gen() {}
}
```

これは次のようになります。

```js
class A {
  a = 1 \* gen() {}
}
```

したがって、 `{` のあたりで構文エラーになります。

セミコロンなしのスタイルを強制したい場合、 ASI を扱う上で以下のような経験則があります。

* 後置 `++` および `--` は、オペランドと同じ行に書く。
* `return`、`throw`、`yield` の後の式はキーワードと同じ行に置く。
* 同様に、 `break` または `continue` の後のラベルはキーワードと同じ行に置く。
* アロー関数の `=>` は引数の末尾と同じ行に置く。
* 非同期関数やメソッドの `async` の直後で改行しない。
* 行が `(`, `[`, ```, `+`, `-`, `/` (正規表現リテラル) で始まる場合は、直前にセミコロンを置くか、前の行の行末にセミコロンをつける。
* クラスのフィールドは、できれば常にセミコロンで終わるようにします。一つ前のルール（フィールド宣言の後に計算されたプロパティが続くと、その後は `[` で始まる）に加えて、セミコロンはフィールド宣言とジェネレーターメソッドの間にも必要です。
ブラウザーの互換性
---------

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

関連情報
----

* Lexical grammar in the ECMAScript specification
* Jeff Walden: Binary and octal numbers
* Mathias Bynens: JavaScript character escape sequences
* 論理型
* 数値型
* 文字列型
* `RegExp`


式と演算子 - JavaScript

式と演算子
=====

この節では、JavaScript 言語のすべての演算子、式、キーワードについて記述しています。

式と演算子（カテゴリー別）
-------------

アルファベット順の一覧は左側のサイドバーをご覧ください。

### 基本式

JavaScript での基本的なキーワードと一般的な式です。これらの式は最も高い優先順位を持ちます（演算子よりも高い）。

`this`

`this` キーワードは関数の実行コンテキストを示す特別なプロパティです。

リテラル

基本的な `null`、論理値、数値、文字列のリテラルです。

`[]`

配列初期化子またはリテラル構文です。

`{}`

オブジェクト初期化子またはリテラル構文です。

`function`

`function` キーワードは関数式を定義します。

`class`

`class` キーワードはクラス式を定義します。

`function*`

`function*` キーワードはジェネレーター関数式を定義します。

`async function`

`async function` は非同期関数式を定義します。

`async function*`

`async function*` キーワードは非同期ジェネレーター関数式を定義します。

`/ab+c/i`

正規表現リテラル構文です。

``string``

テンプレートリテラル構文です。

`( )`

グループ化演算子です。

### 左辺式

左辺値は、代入の対象になります。

プロパティアクセサー

プロパティアクセス演算子はオブジェクトのプロパティやメソッドへのアクセス (`object.property` や `object["property"]`) を提供します。

`?.`

オプショナルチェーン演算子は、参照が nullish（`null` または `undefined`）であった場合にエラーを発生させる代わりに `undefined` を返します。

`new`

`new` 演算子はコンストラクターのインスタンスを作成します。

`new.target`

コンストラクター内で `new.target` を使うことで、`new` によって呼び出されるコンストラクターを参照できます。

`import.meta`

コンテキストに依存したメタデータを JavaScript モジュールへ公開するオブジェクトです。

`super`

`super`キーワードは親オブジェクトのコンストラクタを呼び出したり、親オブジェクトのプロパティにアクセスしたりすることができます。

`import()`

`import()` 構文を使うと、モジュールを非同期かつ動的に、潜在的にモジュールでない環境に読み込むことができます。

### インクリメントとデクリメント

後置/前置のインクリメント演算子と後置/前置のデクリメント演算子です。

`A++`

後置型インクリメント演算子。

`A--`

後置型デクリメント演算子。

`++A`

前置型インクリメント演算子。

`--A`

前置型デクリメント演算子。

### 単項演算子

単項演算は、単一のオペランドによる演算です。

`delete`

`delete` 演算子は、オブジェクトからプロパティを削除します。

`void`

`void` 演算子は、式の返値を破棄します。

`typeof`

`typeof` 演算子は、与えられたオブジェクトの型を判別します。

`+`

単項正値演算子は、そのオペランドを数値型に変換します。

`-`

単項負値演算子は、そのオペランドを数値型に変換して正負を反転します。

`~`

ビット否定演算子です。

`!`

論理否定演算子です。

`await`

非同期関数式の停止/再開と、プロミスの履行/拒否を待ちます。

### 算術演算子

算術演算子は、数値（リテラルまたは値）をオペランドとして取り、1 個の数値を返します。

`**`

べき乗演算子です。

`*`

乗算演算子です。

`/`

除算演算子です。

`%`

剰余演算子です。

`+` （プラス）

加算演算子です。

`-`

減算演算子です。

### 関係演算子

比較演算子はオペランド同士を比較し、その比較結果が真かどうかに基づいて論理値を返します。

`<` (Less than)

小なり演算子です。

`>` (Greater than)

大なり演算子です。

`<=`

小なりイコール演算子です。

`>=`

大なりイコール演算子です。

`instanceof`

`instanceof` 演算子は、オブジェクトが別のオブジェクトのインスタンスかどうかを判別します。

`in`

`in` 演算子は、与えられたプロパティをオブジェクトが持っているかどうかを判別します。

**メモ:** `=>` は演算子ではなく、アロー関数のための記法です。

### 等値演算子

等値演算子の評価結果は常に、比較が真かどうかに基づいて論理型の値になります。

`==`

等値演算子です。

`!=`

不等値演算子です。

`===`

同値演算子です。

`!==`

非同値演算子です。

### ビットシフト演算子

オペランドのすべてのビットをシフト演算します。

`<<`

ビット左シフト演算子です。

`>>`

ビット右シフト演算子です。

`>>>`

ビット符号なし右シフト演算子です。

### バイナリービット演算子

ビット演算子は、そのオペランドを 32 ビット（0 と 1）の並びとして扱い、標準の JavaScript 数値を返します。

`&`

ビット論理積 (AND) です。

`|`

ビット論理和 (OR) です。

`^`

ビット排他的論理和 (XOR) です。

### バイナリー論理演算子

論理演算子は論理値（ブール値）において実装され、短絡評価があります。

`&&`

論理積 (AND) です。

`||`

論理和 (OR) です。

`??`

Null 合体演算子です。

### 条件（三項）演算子

`(条件 ? 真の場合 : 負の場合)`

この条件演算子は、条件の論理値を基に、2 つの値のいずれか一方を返します。

### 代入演算子

代入演算子は、右辺のオペランドに基づいて、値を左辺のオペランドに代入します。

`=`

代入演算子です。

`*=`

乗算値を代入します。

`/=`

除算値を代入します。

`%=`

剰余値を代入します。

`+=`

加算値を代入します。

`-=`

減算値を代入します。

`<<=`

左シフトした値を代入します。

`>>=`

右シフトした値を代入します。

`>>>=`

符号なしの右シフトした値を代入します。

`&=`

ビット論理積 (AND) の値を代入します。

`^=`

ビット排他的論理和 (XOR) の値を代入します。

`|=`

ビット論理和 (OR) の値を代入します。

`**=`

べき乗値を代入します。

`&&=`

論理積代入です。

`||=`

論理和代入です。

`??=`

論理 Null 合体代入です。

`[a, b] = arr`, `{ a, b } = obj`

分割代入は、配列やオブジェクトのプロパティを、配列やオブジェクトリテラルに似た構文を使用して変数に代入します。

### yield 演算子

`yield`

ジェネレーター関数の一時停止と再開を行います。

`yield*`

別のジェネレーター関数または反復可能オブジェクトを代行します。

### スプレッド構文

`...obj`

スプレッド構文を使用すると、配列や文字列などの反復可能オブジェクトを、 0 個以上の引数（関数呼び出しの場合）や要素（配列リテラルの場合）が予想される配置で展開することができます。オブジェクトリテラルでは、スプレッド構文はオブジェクトのプロパティを列挙し、作成するオブジェクトにキーと値のペアを追加します。

### カンマ演算子

`,`

カンマ演算子は、複数の式を単一の文で評価し、最後の式の結果を返すことができます。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-addition-operator-plus |
| ECMAScript Language Specification # sec-assignment-operators |
| ECMAScript Language Specification # sec-async-function-definitions |
| ECMAScript Language Specification # sec-async-generator-function-definitions |
| ECMAScript Language Specification # prod-BitwiseANDExpression |
| ECMAScript Language Specification # sec-bitwise-not-operator |
| ECMAScript Language Specification # prod-BitwiseORExpression |
| ECMAScript Language Specification # prod-BitwiseXORExpression |
| ECMAScript Language Specification # sec-class-definitions |
| ECMAScript Language Specification # sec-comma-operator |
| ECMAScript Language Specification # sec-conditional-operator |
| ECMAScript Language Specification # sec-postfix-decrement-operator |
| ECMAScript Language Specification # sec-delete-operator |
| ECMAScript Language Specification # sec-destructuring-assignment |
| ECMAScript Language Specification # sec-destructuring-binding-patterns |
| ECMAScript Language Specification # sec-multiplicative-operators |
| ECMAScript Language Specification # sec-equality-operators |
| ECMAScript Language Specification # sec-exp-operator |
| ECMAScript Language Specification # sec-function-definitions |
| ECMAScript Language Specification # sec-generator-function-definitions |
| ECMAScript Language Specification # sec-relational-operators |
| ECMAScript Language Specification # sec-grouping-operator |
| ECMAScript Language Specification # sec-import-calls |
| ECMAScript Language Specification # prod-ImportMeta |
| HTML Standard # hostgetimportmetaproperties |
| ECMAScript Language Specification # sec-postfix-increment-operator |
| ECMAScript Language Specification # sec-left-shift-operator |
| ECMAScript Language Specification # prod-LogicalANDExpression |
| ECMAScript Language Specification # sec-logical-not-operator |
| ECMAScript Language Specification # prod-LogicalORExpression |
| ECMAScript Language Specification # sec-new-operator |
| ECMAScript Language Specification # sec-built-in-function-objects |
| ECMAScript Language Specification # sec-null-value |
| ECMAScript Language Specification # prod-CoalesceExpression |
| ECMAScript Language Specification # sec-object-initializer |
| ECMAScript Language Specification # prod-OptionalExpression |
| ECMAScript Language Specification # sec-property-accessors |
| ECMAScript Language Specification # sec-signed-right-shift-operator |
| ECMAScript Language Specification # prod-SpreadElement |
| ECMAScript Language Specification # prod-ArgumentList |
| ECMAScript Language Specification # prod-PropertyDefinition |
| ECMAScript Language Specification # sec-subtraction-operator-minus |
| ECMAScript Language Specification # sec-super-keyword |
| ECMAScript Language Specification # sec-this-keyword |
| ECMAScript Language Specification # sec-typeof-operator |
| ECMAScript Language Specification # sec-unary-minus-operator |
| ECMAScript Language Specification # sec-unary-plus-operator |
| ECMAScript Language Specification # sec-unsigned-right-shift-operator |
| ECMAScript Language Specification # sec-void-operator |
| ECMAScript Language Specification # prod-YieldExpression |
| 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.

関連情報
----

* 演算子の優先順位


反復処理プロトコル - JavaScript

反復処理プロトコル
=========

**反復処理プロトコル**は、新しい組み込みオブジェクトや構文ではなく**プロトコル**です。これらのプロトコルは以下のような単純な約束事によって、すべてのオブジェクトで実装することができます。

プロトコルは 2 つあります。反復可能プロトコルとイテレータープロトコルです。

反復可能プロトコル
---------

**反復可能プロトコル** (The iterable protocol) によって、 JavaScript のオブジェクトは反復動作を定義またはカスタマイズすることができます。例えば、 `for...of` 構造の中でどの値がループに使われるかです。一部の組み込み型は既定の反復動作を持つ組み込み反復可能オブジェクトで、これには `Array` や `Map` がありますが、他の型 (`Object` など) はそうではありません。

**反復可能**であるために、オブジェクトは **`@@iterator`** メソッドを実装する必要があります。これはつまり、オブジェクト（または、プロトタイプチェーン上のオブジェクトの一つ）が `Symbol.iterator` 定数にて利用できる `@@iterator` キーのプロパティを持つ必要があります。

`[Symbol.iterator]`

イテレータープロトコルに準拠するオブジェクトを返す、引数なしの関数。

（`for...of` ループの始まりのように）オブジェクトが反復される必要があるときはいつでも、その `@@iterator` メソッドが引数なしで呼ばれます。そして、返される**イテレーター**は、反復される値を取得するために使用されます。

なお、この引数なしの関数が呼び出されると、反復可能オブジェクト上のメソッドとして呼び出されます。従って関数の中では、 `this` キーワードを反復可能オブジェクトのプロパティにアクセスするために使用して、反復の間に何を提供するかを決めることができます。

この関数は普通の関数、またはジェネレーター関数にすることができ、そのため呼び出されると、イテレーターオブジェクトが返されます。このジェネレーター関数の中では `yield` を使用してそれぞれの項目を提供することができます。

イテレータープロトコル
-----------

**イテレーター（反復子）プロトコル** (The iterator protocol)
 は、値の並び（有限でも無限でも）を生成するための標準的な方法と、すべての値が生成された場合の返値を定義します。

以下の意味で **`next()`** メソッドを実装していれば、オブジェクトはイテレーターになります。

`next()`

0 個または 1 個の引数を受け入れ、`IteratorResult` インターフェイス（下記参照）に適合したオブジェクトを返す関数です。組み込み言語機能（`for...of` など）がイテレーターを使用しているときに、オブジェクト以外の値（`false` や `undefined` など）を返した場合、`TypeError` (`"iterator.next() returned a non-object value"`) が発生します。

イテレータープロトコルのすべてのメソッド（`next()`、`return()`、`throw()`）は、`IteratorResult` インターフェイスを実装したオブジェクトを返すことが期待されています。このオブジェクトは以下のプロパティを持つ必要があります。

`done` 省略可

イテレーターがシーケンス内の次の値を生成できるとき `false` の値になります。（これは `done` プロパティが指定されていない場合も同じです。）

イテレーターが反復シーケンスを終了した場合、`true` の値になります。この場合、`value` は任意でイテレーターの返値を指定します。

`value` 省略可

イテレーターによって返される任意の JavaScript 値。`done` が `true` のときは省略することができます。

実際には、どちらのプロパティも厳密には必要ありません。どちらのプロパティも持たないオブジェクトを返した場合、それは事実上 `{ done: false, value: undefined }` と同じです。

イテレーターが `done: true` の結果を返した場合、それ以降に `next()` を呼び出すと、同様に `done: true` を返すことが期待されますが、これは言語レベルでは強制されるものではありません。

`next` メソッドは、メソッド本体が利用できるようになる値を受け取ることができます。組み込みの言語機能では、値を渡すことはありません。ジェネレーターの `next` メソッドに渡される値は、対応する `yield` 式の値になる。

オプションとして、イテレーターは **`return(value)`** と **`throw(exception)`** メソッドも実装することができます。これらのメソッドは、呼び出されると、呼び出し側がイテレーターの反復処理を終了し、（データベース接続を閉じるなどの）必要なクリーンアップを実行できることをイテレーターに指示します。

`return(value)` 省略可

0 または 1 つの引数を受け入れ、`IteratorResult` インターフェイスに適合したオブジェクトを返す関数で、通常 `value` は渡された `value` と等しく、`done` は `true` と等しくなります。このメソッドを呼び出すと、呼び出し側がこれ以上 `next()` を呼び出さないことをイテレーターに指示し、任意のクリーンアップ処理を実行することができます。

`throw(exception)` 省略可

0 個または 1 個の引数を受け入れ、`IteratorResult` インターフェースに適合したオブジェクトを返す関数であり、通常 `done` は `true` に等しくなります。このメソッドを呼び出すと、呼び出し側がエラー状態を検出したことをイテレーターに指示し、`exception` は通常 `Error` インスタンスとなります。

**メモ:** 特定のオブジェクトがイテレータープロトコルを実装しているかどうかを反射的に（つまり、実際に `next()` を呼び出して、返された結果を検証することなく）知ることは不可能です。

イテレーターはとても簡単に反復可能オブジェクトにすることができます。`[@@iterator]()` メソッドを実装して `this` を返すだけです。

```js
// イテレーターと反復可能の両プロトコルを満たす
const myIterator = {
  next() {
    // ...
  },
  [Symbol.iterator]() {
    return this;
  },
};
```

このようなオブジェクトは**反復可能イテレーター**と呼ばれます。このように実装することで、反復可能オブジェクトを期待する様々な構文でイテレーターが利用できるようになります。したがって、反復可能プロトコルを実装せずにイテレータープロトコルを実装することは、ほとんど有益ではありません。（実際、ほとんどすべての構文と API はイテレーターではなく反復可能を期待しています。）ジェネレーターオブジェクトがその例です。

```js
const aGeneratorObject = (function\* () {
  yield 1;
  yield 2;
  yield 3;
})();

console.log(typeof aGeneratorObject.next);
// "function" — （正しい結果を返す）next メソッドを持っているのでイテレーター

console.log(typeof aGeneratorObject[Symbol.iterator]);
// "function" — （正しいイテレーターを返す）@@iterator メソッドを持っているので反復可能オブジェクト

console.log(aGeneratorObject[Symbol.iterator]() === aGeneratorObject);
// true — @@iterator メソッドは自分自身（イテレータ）を返すので、反復可能なイテレーター
```

組み込みのイテレーターはすべて `Iterator.prototype` を継承しており、 `[@@iterator]()` メソッドは `this` を返すものとして実装されているので、組み込みイテレーターも反復可能なものとなっています。

しかし、可能であれば `iterable[Symbol.iterator]` が `Set.prototype[@@iterator]()` が行うように、常に先頭から始まる別のイテレーターを返すほうが良いでしょう。

非同期イテレーターと非同期反復可能プロトコル
----------------------

非同期の反復処理に用いるプロトコルには、**非同期イテレーター**と**非同期反復可能オブジェクト**という名前の別の組があります。これらは反復可能オブジェクトとイテレータープロトコルに比べて非常によく似たインターフェイスを持っていますが、イテレーターメソッドの呼び出しからの返値がそれぞれプロミスでラップされている点が異なります。

オブジェクトが非同期イテレータープロトコルを実装するのは、以下のメソッドを実装している場合です。

`[Symbol.asyncIterator]`

非同期イテレータープロトコルに準拠し、オブジェクトを返す引数ゼロの関数です。

オブジェクトが非同期イテレータープロトコルを実装するのは、以下のメソッドを実装している場合です。

`next()`

0 個または 1 個の引数を受け入れ、プロミスを返す関数です。プロミスは `IteratorResult` インターフェイスに準拠したオブジェクトに履行され、プロパティは同期イテレーターのものと同じ意味づけを持ちます。

`return(value)` 省略可

0 個または 1 個の引数を受け入れ、プロミスを返す関数です。プロミスは `IteratorResult` インターフェイスに準拠したオブジェクトに履行され、プロパティは同期イテレーターのものと同じ意味づけを持ちます。

`throw(exception)` 省略可

0 個または 1 個の引数を受け入れ、プロミスを返す関数です。プロミスは `IteratorResult` インターフェイスに準拠したオブジェクトに履行され、プロパティは同期イテレーターのものと同じ意味づけを持ちます。

言語と反復処理プロトコルの対話
---------------

この言語では、反復可能オブジェクトとイテレーターを生成または使用する API を規定しています。

### 組み込み反復可能オブジェクト

`String`、`Array`、`TypedArray`、`Map`、`Set`、`Segments` （`Intl.Segmenter.prototype.segment()` で返される）は、すべて組み込み反復可能オブジェクトです。それらの `prototype` オブジェクトはそれぞれ `@@iterator` メソッドを実装しています。また、`arguments` オブジェクトや `NodeList` などの一部の DOM コレクション型も反復可能です。
 `ReadableStream`は、執筆時点では唯一の組み込み非同期反復可能オブジェクトです。

ジェネレータ関数は、反復可能なイテレーターであるジェネレータオブジェクトを返します。非同期ジェネレータ関数は、非同期反復可能なイテレータである非同期 ジェネレーターオブジェクトを返します。

組み込み反復可能オブジェクトから返されるイテレーターは、実際にはすべて共通のクラス `Iterator` （現在は未公開）を継承しており、前述の `[Symbol.iterator]() { return this; }` メソッドを実装しているので、すべて反復可能イテレーターとなっています。将来的には、これらの組み込みイテレーターは、イテレータープロトコルが要求する `next()` メソッドに加えて、追加のヘルパーメソッドを持つことができます。イテレーターのプロトタイプチェーンは、グラフィカルコンソールにログ出力することで検査することができます。
```

console.log([][Symbol.iterator]());

Array Iterator {}
  [[Prototype]]: Array Iterator     ==> 配列のイテレーターに共通するプロトタイプ
    next: ƒ next()
    Symbol(Symbol.toStringTag): "Array Iterator"
    [[Prototype]]: Object           ==> すべての組み込みイテレーターに共通するプロトタイプ
      Symbol(Symbol.iterator): ƒ [Symbol.iterator]()
      [[Prototype]]: Object         ==> これは Object.prototype
```

### 反復可能オブジェクトを受け入れる組み込み API

反復可能オブジェクトを受け入れる API はたくさんあります。以下はその例です。

* `Map()`
* `WeakMap()`
* `Set()`
* `WeakSet()`
* `Promise.all()`
* `Promise.allSettled()`
* `Promise.race()`
* `Promise.any()`
* `Array.from()`

```js
const myObj = {};

new WeakSet(
  (function\* () {
    yield {};
    yield myObj;
    yield {};
  })(),
).has(myObj); // true
```

### 反復可能オブジェクトを期待する構文

一部の文や式は反復可能オブジェクトを期待します。例えば、 `for...of` ループ、配列と引数のスプレッド、`yield*`、配列の分割代入などです。

```js
for (const value of ["a", "b", "c"]) {
  console.log(value);
}
// "a"
// "b"
// "c"

console.log([..."abc"]); // ["a", "b", "c"]

function\* gen() {
  yield\* ["a", "b", "c"];
}

console.log(gen().next()); // { value: "a", done: false }

[a, b, c] = new Set(["a", "b", "c"]);
console.log(a); // "a"
```

組み込み API がイテレーターを反復処理していて、最後の結果の `done` が `false` （イテレーターがさらに値を生成できる状態）だが、それ以上の値は必要ない場合、`return` メソッドが存在すれば、それが呼び出されますこれは例えば、`for...of` ループの中で `break` や `return` に遭遇した場合や、配列の分割代入ですべての識別子が既に結合されている場合などに発生します。

```js
const obj = {
  [Symbol.iterator]() {
    let i = 0;
    return {
      next() {
        i++;
        console.log("Returning", i);
        if (i === 3) return { done: true, value: i };
        return { done: false, value: i };
      },
      return() {
        console.log("Closing");
        return { done: true };
      },
    };
  },
};

const [b] = obj;
// Returning 1
// Closing

const [a, b, c] = obj;
// Returning 1
// Returning 2
// Returning 3
// Already reached the end (the last call returned `done: true`),
// so `return` is not called

for (const b of obj) {
  break;
}
// Returning 1
// Closing
```

非同期反復可能オブジェクトと対話する唯一の方法は、`for await...of` ループと、非同期ジェネレーター関数での `yield*`（ただし同期ジェネレーター関数ではありません）です。非同期反復可能オブジェクトであるが、同期反復可能ではない（つまり `[@@asyncIterator]()` はあるが `[@@iterator]()` はない）ものに `for...of` や配列の展開などを使用すると、TypeError: x is not iterable 例外が発生します。

### 非正規形反復可能オブジェクト

反復可能オブジェクトの `@@iterator` メソッドがイテレーターオブジェクトを返さない場合、それは**非正規形**反復可能オブジェクトと見なされます。

これを使用すると、ランタイムエラーやバグの挙動をもたらす可能性があります。

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

例
-

### ユーザー定義の反復可能オブジェクト

次のようにして、独自の反復可能オブジェクトを作ることができます。

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

console.log([...myIterable]); // [1, 2, 3]
```

### 単純なイテレーター

イテレーターはもともとステートフルなものです。ジェネレーター関数として定義していない場合（上の例が示すように）、クロージャで状態をカプセル化したいと思うことでしょう。

```js
function makeIterator(array) {
  let nextIndex = 0;
  return {
    next() {
      return nextIndex < array.length
        ? {
            value: array[nextIndex++],
            done: false,
          }
        : {
            done: true,
          };
    },
  };
}

const it = makeIterator(["yo", "ya"]);

console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true
```

### 無限のイテレーター

```js
function idMaker() {
  let index = 0;
  return {
    next() {
      return {
        value: index++,
        done: false,
      };
    },
  };
}

const it = idMaker();

console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 2
// ...
```

### ジェネレーターで反復可能プロトコルを定義

```js
function\* makeSimpleGenerator(array) {
  let nextIndex = 0;
  while (nextIndex < array.length) {
    yield array[nextIndex++];
  }
}

const gen = makeSimpleGenerator(["yo", "ya"]);

console.log(gen.next().value); // 'yo'
console.log(gen.next().value); // 'ya'
console.log(gen.next().done); // true

function\* idMaker() {
  let index = 0;
  while (true) {
    yield index++;
  }
}

const it = idMaker();

console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 2
// ...
```

### クラスで反復可能プロトコルを定義

状態のカプセル化は、プライベートプロパティでも行うことができます。

```js
class SimpleClass {
  #data;

  constructor(data) {
    this.#data = data;
  }

  [Symbol.iterator]() {
    // それぞれのイテレーターに新しいインデックスを使用します。これにより
    // break の使用や同じ反復可能オブジェクトに対する入れ子ループなど、自明でない用途で、
    // 反復可能オブジェクトに対する複数の反復処理を安全に行うことができます。
    let index = 0;

    return {
      // 注: アロー関数を使用すると、`next()` の代わりに `[@@iterator]()` の方を `this` が指すようになります。
      next: () => {
        if (index < this.#data.length) {
          return { value: this.#data[index++], done: false };
        } else {
          return { done: true };
        }
      },
    };
  }
}

const simple = new SimpleClass([1, 2, 3, 4, 5]);

for (const val of simple) {
  console.log(val); // 1 2 3 4 5
}
```

### 組み込み反復可能オブジェクトのオーバーライド

例えば、`String` は、組み込みのイテレーターオブジェクトです。

```js
const someString = "hi";
console.log(typeof someString[Symbol.iterator]); // "function"
```

`String` の既定のイテレーターは、文字列のコードポイントを 1 つずつ返します。

```js
const iterator = someString[Symbol.iterator]();
console.log(`${iterator}`); // "[object String Iterator]"

console.log(iterator.next()); // { value: "h", done: false }
console.log(iterator.next()); // { value: "i", done: false }
console.log(iterator.next()); // { value: undefined, done: true }
```

自分自身で `@@iterator` を用意することで、反復処理の動作を再定義することができます。

```js
// 自動ボックス化を避けるため、文字列オブジェクトを明示的に構築する必要があります。
const someString = new String("hi");

someString[Symbol.iterator] = function () {
  return {
    // this is the iterator object, returning a single element (the string "bye")
    next() {
      return this._first
        ? { value: "bye", done: (this._first = false) }
        : { done: true };
    },
    \_first: true,
  };
};
```

`@@iterator` の再定義が、反復処理を使用する組み込みの構成要素の動作にどのような影響を与えるかに注目してください。

```js
console.log([...someString]); // ["bye"]
console.log(`${someString}`); // "hi"
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-iteration |

関連情報
----

* イテレーターとジェネレーター
* `function*`
* `Symbol.iterator`
* `Iterator`


非推奨の機能、廃止された機能 - JavaScript

非推奨の機能、廃止された機能
==============

このページのリストは JavaScript で廃止予定（まだ使用できるが削除する予定）とされた、あるいは既に廃止され使用不可となった機能の一覧です。

非推奨の機能
------

これらの非推奨機能はまだ使用可能かもしれません。しかし将来的には完全に削除されるでしょう。既にコード内でこれらを使用している場合は、代替となるコードに置き換えておく必要があります。

これらの非推奨機能のいくつかは、 ECMAScript 仕様書の付録 B の章に掲載されています。この章は規範的なオプションとして記述されています。つまり、ウェブブラウザーのホストはこれらの機能を実装しなければなりませんが、ウェブ以外のホストは実装しなくても構いません。これらの機能を削除すると後方互換性の問題が発生し、旧形式のウェブサイトが壊れてしまうので、おそらく安定しているのでしょう。（JavaScript で「ウェブを壊すな」という設計目標があります。）それでも、これらはクロスプラットフォームで互換性がなく、すべての解析ツールで対応していないかもしれないので、付録 B の序文にあるように、使用しないことが推奨されます。

>
> ... プログラマーは新しい ECMAScript コードを書くときに、これらの機能や振る舞いを使用したり、その存在を想定したりしてはいけません。...
>
>
>

他にも、仕様書本体にあるとはいえ、規範的なオプションとしてマークされているものもあり、依存してはいけません。

### HTML コメント

JavaScript のソースは、スクリプトとして解釈された場合、あたかもスクリプトが `<script>` タグの一部であるかのように、 HTML 風のコメントが利用できます。

以下は、ウェブブラウザー（または Chrome を駆動する V8 エンジンを使用する Node.js）で実行するときに有効な JavaScript です。

```js
<!-- コメント
console.log("a"); <!-- その他のコメント
console.log("b");
--> さらにコメント
// Logs "a" and "b"
```

`<!--` と `-->` はどちらも `//` のように動作し、行頭のコメントになります。 `-->` は行頭でのみ有効ですが（後置デクリメントや大なり演算子が続く場合の曖昧さを避けるため）、 `<!--` は行のどの位置でも使用することができます。

### RegExp

以下のプロパティは非推奨です。これらは置換文字列で使用しても効果がありません。

| プロパティ | 説明 |
| --- | --- |
| `$1-$9` | もしあれば、括弧で囲まれた部分文字列に一致します。 |
| `$_` | `input` を参照。 |
| `$&` | `lastMatch` を参照。 |
| `$+` | `lastParen` を参照。 |
| `$`` | `leftContext` を参照。 |
| `$'` | `rightContext` を参照。 |
| `input` | 正規表現が一致する対象となる文字列。 |
| `lastMatch` | 最後に一致した文字。 |
| `lastParen` | （もしあれば）最後に括弧で囲まれた部分文字列の一致。 |
| `leftContext` | 一番最近の一致に先行する部分文字列。 |
| `rightContext` | 一番最近の一致の後に続く部分文字列。 |

**警告:** これらの静的プロパティは、外部コードと対話する際の問題を発生させる可能性があるため、使用しないようにしましょう。

`compile()` メソッドは非推奨です。代わりに新しい `RegExp` のインスタンスを構築してください。

### Function

* 関数の `caller` プロパティと `arguments.callee` プロパティは非推奨で、厳格モードでは使用できません。
* 関数のプロパティとして `arguments` にアクセスする代わりに、関数クロージャの内部で `arguments` オブジェクトを使用してください。
### Object

* `Object.prototype.__proto__` アクセサーは非推奨です。代わりに `Object.getPrototypeOf` および `Object.setPrototypeOf` を使用してください。これはオブジェクトリテラルの `__proto__` リテラルキーには適用されません。
* `Object.prototype.__defineGetter__`、`Object.prototype.__defineSetter__`、`Object.prototype.__lookupGetter__`、`Object.prototype.__lookupSetter__` の各メソッドは非推奨です。代わりに `Object.getOwnPropertyDescriptor` や `Object.defineProperty` を使用してください。
### String

* `String.prototype.fontsize` や `String.prototype.big` などの HTML ラッパーメソッド。
* `String.prototype.substr` はおそらくすぐには削除されないと思いますが、付録 B で定義されており、本質的にオプションです。
* `String.prototype.trimLeft` および `String.prototype.trimRight` は `String.prototype.trimStart` と `String.prototype.trimEnd` に置き換えてください。
### Date

* `getYear()` と `setYear()` は「2000年問題」の影響を受けます。代替策として、`getFullYear` および `setFullYear` の使用が推奨されます。
* `toGMTString()` メソッドは非推奨です。代わりに `toUTCString()` を使用してください。
### エスケープシーケンス

* 文字列内と正規表現リテラル内での、8 進表記のエスケープシーケンス (\ に続く、1 つ、2 つ、もしくは、3 つの 8 進表現の数字) は非推奨です。
* `escape` と `unescape` 関数は非推奨です。特殊文字のためのエスケープシーケンスをエンコードかデコードするためには、`encodeURI`、`encodeURIComponent`、`decodeURI`、`decodeURIComponent` を使用してください。
### 文

`with` 文は非推奨であり、厳格モードでは利用できません。

`for...in` ループヘッダーの `var` 宣言での初期化子は非推奨であり、厳格モードでは構文エラーになります。厳格モードでない場合は、黙って無視されます。

廃止された機能
-------

これらの廃止された機能は、 JavaScript から完全に削除され、表示されているバージョンの JavaScript からは使用できなくなりました。

### RegExp

以下のプロパティは `RegExp` インスタンスのものとなり、 `RegExp` コンストラクターのものではなくなりました。

| プロパティ | 説明 |
| --- | --- |
| `global` | 文字列中の使用可能なすべての照合に対して正規表現をテストするか、最初の照合のみに対してテストするかを指定します。 |
| `ignoreCase` | 文字列の照合を試みる際に、大文字と小文字を無視するかどうかを指定します。 |
| `lastIndex` | 次の照合を始める位置のインデックス。 |
| `multiline` (`RegExp.$*` でも) | 複数行にまたがる文字列を検索するかどうか。 |
| `source` | パターンのテキストです。 |

`valueOf()` メソッドは、 `RegExp` に特化したメソッドではなくなりました。自分自身を返す `Object.prototype.valueOf()` を使用します。

### Function

* Function の `arity` プロパティは廃止されました。代わりに `length` を使用してください。
### Object

| プロパティ | 説明 | 代替 |
| --- | --- | --- |
| `__count__` | ユーザー定義オブジェクトに直接定義された列挙可能なプロパティの数を返します。 | `Object.keys()` |
| `__parent__` | オブジェクトのコンテキストを指し示します。 | 直接の置き換えなし |
| `__iterator__` | 旧形式のイテレーターと共に使用 | `Symbol.iterator` および新しい反復処理プロトコル |
| `__noSuchMethod__` | 存在しないプロパティがメソッドとして呼ばれたときに呼び出されるメソッド。 | `Proxy` |
| `Object.prototype.eval()` | 指定したオブジェクトのコンテキスト内の JavaScript コードの文字列を評価します。 | 直接の置き換えなし |
| `Object.observe()` | オブジェクトに対する変更を非同期に監視します。 | `Proxy` |
| `Object.unobserve()` | オブザーバーを削除します。 | `Proxy` |
| `Object.getNotifier()` | `Object.observe()` で変更観測を合成的に発生させることができる通知オブジェクトを作成します。 | 直接の置き換えなし |
| `Object.prototype.watch()` | プロパティが代入されたときに呼び出されるハンドラーコールバックをプロパティに取り付けます。 | `Proxy` |
| `Object.prototype.unwatch()` | プロパティの監視ハンドラーを削除します。 | `Proxy` |

### String

* 標準外の String の汎用メソッド、たとえば `String.slice(myStr, 0, 12)`, `String.replace(myStr, /./g, "!")` などは、 Firefox 1.5 (JavaScript 1.6) で導入され、Firefox 53 で非推奨となり、そして Firefox 68 で廃止されました。代わりに `String.prototype` 上のメソッドを `Function.call` と共に使用することができます。
* `String.prototype.quote` は Firefox 37 で削除されました。
* 標準外の `flags` 引数は `String.prototype.search`, `String.prototype.match`, `String.prototype.replace` で廃止されました。
### WeakMap

* `WeakMap.prototype.clear()` は Firefox 20 で追加され、 Firefox 46 で削除されました。 `WeakMap` ではすべてのキーを操作することはできません。
### Date

* `Date.prototype.toLocaleFormat()` は廃止されました。代わりに `toLocaleString` または `Intl.DateTimeFormat` を使用してください。
### Array

* 標準外の Array の汎用メソッド、例えば `Array.slice(myArr, 0, 12)`, `Array.forEach(myArr, myFn)` などは、 Firefox 1.5 (JavaScript 1.6) で導入され、Firefox 68 で非推奨となり、Firefox 71 で削除されました。代わりに `Array.prototype` 上のメソッドを `Function.call` と共に使用することができます。

| プロパティ | 説明 | 代替 |
| --- | --- | --- |
| `Array.observe()` | 配列に対する変更を非同期に監視します。 | `Proxy` |
| `Array.unobserve()` | オブザーバーを削除します。 | `Proxy` |

### Number

* `Number.toInteger()` は廃止されました。代わりに `Math.floor`、`Math.round`、その他のメソッドを使用してください。
### Proxy

* `Proxy.create` および `Proxy.createFunction` は非推奨です。代わりに `Proxy()` コンストラクターを使用してください。
* 以下のトラップは廃止されました。
    + `hasOwn` (バグ 980565, Firefox 33)
    + `getEnumerablePropertyKeys` (バグ 783829, Firefox 37)
    + `getOwnPropertyNames` (バグ 1007334, Firefox 33)
    + `keys` (バグ 1007334, Firefox 33)
### ParallelArray

* `ParallelArray` は廃止されました。
### 文

* `for each...in` は廃止されました。代わりに `for...of` を使用してください。
* let ブロックと let 式は廃止されました。
* 式クロージャは廃止されました。代わりに通常の関数またはアロー関数を使用してください。
### ソーステキストの取得

配列、数値、文字列などの `toSource()` メソッドと `uneval()` グローバル関数は廃止されました。代わりに `toString()` を使用するか、自分自身でシリアライゼーションメソッドを書いてください。

### 旧形式のジェネレーターとイテレーター

旧形式のジェネレーター関数文と旧形式のジェネレーター関数式は削除されました。旧形式のジェネレーター関数の構文は `function` キーワードを再利用しており、本体に 1 つ以上の `yield` 式があると自動的にジェネレーター関数になります - これは今では構文エラーになっています。代わりに `function*` 文と `function*` 式を使用するようにしてください。

配列内包とジェネレーター内包が削除されました。
```

// 古い配列内包
[for (x of iterable) x]
[for (x of iterable) if (condition) x]
[for (x of iterable) for (y of iterable) x + y]

// 旧形式のジェネレーターの内包
(for (x of iterable) x)
(for (x of iterable) if (condition) x)
(for (x of iterable) for (y of iterable) x + y)
```

バージョン 26 以前の Firefox では、標準のイテレータープロトコルに類似した別のイテレータープロトコルを実装していました。オブジェクトが `next()` メソッドを実装しており、呼び出すたびに値を生成し、反復処理の終わりには `StopIteration` オブジェクトを投げている場合は、そのオブジェクトは古いイテレーターであると言えます。この古いイテレーターのプロトコルは、標準的なイテレーターのプロトコルとは異なる形をとっています。

* 値は `IteratorResult` オブジェクトの `value` プロパティではなく、 `next()` 呼び出しの返値として直接返されていました。
* 反復処理の終了は、`IteratorResult` オブジェクトの `done` プロパティを通じてではなく、 `StopIteration` オブジェクトを投げることで表現されていました。

この機能は、`StopIteration` グローバルコンストラクタとともに、 Firefox 58+ で削除されました。将来に向けた使用方法としては、`for...of` ループとイテレータープロトコルを使用することを検討してください。

### シャープ変数

シャープ変数は廃止されました。循環構造を作成するには、一時変数を使用してください。


単語境界アサーション: \b, \B - JavaScript

単語境界アサーション: \b, \B
==================

**単語境界アサーション**は、文字列の現在の位置が単語境界であるかどうかを調べます。単語境界とは、次の文字が単語文字で、前の文字が単語文字でない場合、またはその逆の場合です。

構文
--

```regex
\b
\B
```

解説
--

`\b` は文字列の現在の位置が単語境界であることを表明します。`\B` はこの表明とは逆で、現在の位置が単語境界でないことを表明します。両者ともアサーションなので、他の文字エスケープや文字クラスエスケープとは異なり、`\b` と `\B` は文字を消費しません。

単語文字は次の通りです。

* 英文字 (A–Z, a–z)、数字 (0–9)、アンダースコア (\_)。
* 正規表現が Unicode 対応で `i` フラグが設定されている場合、大文字小文字の変換によって上記の文字のいずれかに正規化される他の Unicode 文字。

単語文字は `\w` 文字クラスエスケープでも一致します。

範囲外の入力位置は非単語文字とみなされます。 例えば、次の例は照合に成功します。

```js
/\ba/.exec("abc");
/c\b/.exec("abc");

/\B /.exec(" abc");
/ \B/.exec("abc ");
```

例
-

### 単語の検出

次の例は、文字列が "thanks" または "thank you" という単語を含んでいるかどうかを検出します。

```js
function hasThanks(str) {
  return /\b(thanks|thank you)\b/i.test(str);
}

hasThanks("Thanks! You helped me a lot."); // true
hasThanks("Just want to say thank you for all your work."); // true
hasThanks("Thanksgiving is around the corner."); // false
```

**警告:** すべての言語で単語の境界が明確に定義されているわけではありません。日本語やタイ語のように空白の区切りがない言語を扱う場合は、代わりに `Intl.Segmenter` のような高度なライブラリーを使って単語を検索してください。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-Assertion |

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

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

関連情報
----

* アサーション
* 正規表現リファレンス
* 入力境界アサーション: `^`, `$`
* 先読みアサーション: `(?=...)`, `(?!...)`
* 後読みアサーション: `(?<=...)`, `(?<!...)`
* 文字エスケープ: `\n`, `\u{...}`


後方参照: \1, \2 - JavaScript

後方参照: \1, \2
============

**後方参照**は、前回のキャプチャグループの部分一致を参照し、そのグループと同じテキストに一致します。名前付きキャプチャグループの場合は、名前付き後方参照構文を使用する方ができればよいでしょう。

構文
--

```regex
\N
```

**メモ:** `N` はリテラル文字ではありません。

### 引数

`N`

キャプチャグループの番号を参照する正の値。

解説
--

後方参照は、前回キャプチャグループによって一致したのと同じテキストに一致する方法です。キャプチャリンググループは 1 から数えるので、最初のキャプチャリンググループの結果は `\1` で参照し、2 つ目は `\2` で参照し、といった具合になります。`\0` は NUL 文字の文字エスケープです。

大文字と小文字を区別しない照合では、後方参照は元のテキストと異なる大文字と小文字を持つテキストと一致することがあります。

```js
/(b)\1/i.test("bB"); // true
```

後方参照は存在するキャプチャグループを参照しなければなりません。指定する数がキャプチャグループの総数より大きい場合、構文エラーが発生します。

```js
/(a)\2/u; // SyntaxError: Invalid regular expression: Invalid escape
```

Unicode 対応モードでない場合は、無効な後方参照は古い 8 進エスケープシーケンスになります。これはウェブの互換性のために非推奨の構文ですので、頼ってはいけません。

```js
/(a)\2/.test("a\x02"); // true
```

参照するキャプチャグループが一致しない場合（例えば、それが論理和の一致しない選択肢に属するため）、または、グループがまだ一致 していない場合（例えば、それが後方参照の正しい位置にあるため）、後方参照は常に成功します（空文字列に一致するかのように）。

```js
/(?:a|(b))\1c/.test("ac"); // true
/\1(a)/.test("a"); // true
```

例
-

### 引用符のペアリング

以下の関数は、文字列中の `title='xxx'` と `title="xxx"` のパターンに一致します。引用符が確実に一致するように、後方参照を使用して最初の引用符を参照します。2 つ目のキャプチャグループ (`[2]`) にアクセスすると、一致する引用符の間の文字列を返します。

```js
function parseTitle(metastring) {
  return metastring.match(/title=(["'])(.\*?)\1/)[2];
}

parseTitle('title="foo"'); // 'foo'
parseTitle("title='foo' lang='en'"); // 'foo'
parseTitle('title="Named capturing groups\' advantages"'); // "Named capturing groups' advantages"
```

### 重複する単語の照合

以下の関数は、文字列中の重複する単語（通常はタイプミス）を探します。なお、`\w` 文字クラスエスケープ は英字にのみ一致しますが、アクセント付きの文字や他のアルファベットには一致しません。より一般的な照合を行いたい場合は、文字列を空白で分割し、結果の配列を反復処理するとよいでしょう。

```js
function findDuplicates(text) {
  return text.match(/\b(\w+)\s+\1\b/i)?.[1];
}

findDuplicates("foo foo bar"); // 'foo'
findDuplicates("foo bar foo"); // undefined
findDuplicates("Hello hello"); // 'Hello'
findDuplicates("Hello hellos"); // undefined
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-DecimalEscape |

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

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

関連情報
----

* グループと後方参照
* 正規表現リファレンス
* キャプチャグループ: `(...)`
* 名前付きキャプチャグループ: `(?<name>...)`
* 名前付き後方参照: `\k<name>`


数量詞: *, +, ?, {n}, {n,}, {n,m} - JavaScript

数量詞: \*, +, ?, {n}, {n,}, {n,m}
===============================

**数量詞**は、アトムを指定した回数繰り返します。数量詞は適用するアトムの後に配置します。

構文
--

```regex
// 貪欲
atom?
atom\*
atom+
atom{count}
atom{min,}
atom{min,max}

// 非貪欲
atom??
atom\*?
atom+?
atom{count}?
atom{min,}?
atom{min,max}?
```

### 引数

`atom`

単一のアトムです。

`count`

非負の整数です。アトムが繰り返される回数です。

`min`

非負の整数です。アトムが繰り返すことができる最小回数です。

`max` 省略可

非負の整数です。アトムが繰り返すことができる最大回数です。小りゃうした場合、アトムは必要なだけ繰り返されます。

解説
--

数量詞はアトムの後に置かれ、そのアトムを一定回数繰り返します。単独で現れることはありません。それぞれの数量詞は、パターンが繰り返されなければならない最小数と最大数を指定することができます。

| 数量詞 | 最小値 | 最大値 |
| --- | --- | --- |
| `?` | 0 | 1 |
| `*` | 0 | 無限大 |
| `+` | 1 | 無限大 |
| `{count}` | `count` | `count` |
| `{min,}` | `min` | 無限大 |
| `{min,max}` | `min` | `max` |

`{count}`、`{min,}`、`{min,max}` の構文では、数値の周りに空白を入れることはできません。そうしないとリテラルのパターンになります。

```js
const re = /a{1, 3}/;
re.test("aa"); // false
re.test("a{1, 3}"); // true
```

この動作は Unicode 対応モードで修正され、中括弧をエスケープなしでリテラルに入れることができなくなりました。`{` と `}` がエスケープなしでリテラルとして使用できるというのはウェブの互換性のための非推奨構文としてのみ認められており、頼ってはいけません。

```js
/a{1, 3}/u; // SyntaxError: Invalid regular expression: Incomplete quantifier
```

最小値が最大値より大きいと構文エラーになります。

```js
/a{3,2}/; // SyntaxError: Invalid regular expression: numbers out of order in {} quantifier
```

数量詞によって、キャプチャグループを複数回照合させることができます。この場合の動作については、キャプチャグループのページを参照してください。

一致するごとに文字列が同じである必要はありません。

```js
/[ab]\*/.exec("aba"); // ['aba']
```

数量詞は既定では貪欲です。つまり、最大値に達するまで、あるいはそれ以上一致させることができなくなるまで、可能な限り何度でも照合しようとします。数量詞の後に `?` を付けることで、貪欲でない数量詞にすることができます。この場合、数量詞はできる限り一致回数を少なくさせようとし、残りのパターンをこの回数で一致させることができなくなった場合のみ、それ以上の回数を照合しようとします。

```js
/a\*/.exec("aaa"); // ['aaa']; 入力全体が消費される
/a\*?/.exec("aaa"); // ['']; 文字を消費しなくても、一致することは可能
/^a\*?$/.exec("aaa"); // ['aaa']; 消費する文字数を減らすことは不可能だが、照合には成功する
```

ただし、あるインデックスで正規表現が文字列と一致すると、それ以降のインデックスを試さなくなります。

```js
/a\*?$/.exec("aaa"); // ['aaa']; 照合は最初の文字ですでに成功しているので、正規表現は 2 文字目で照合を開始しようとしません。
```

貪欲な数量詞は、それ以外のパターンに一致することが不可能な場合、反復回数を少なくしようとするかもしれません。

```js
/[ab]+[abc]c/.exec("abbc"); // ['abbc']
```

この例では、最初の `[ab]+` は貪欲に "abb" に一致しますが、`[abc]c` は残りのパターン ("c") に一致することができないので、数量詞は "ab" だけに一致するように縮小されます。

貪欲な数量詞は、無限個の空文字列と一致することを避けます。 照合する文字数が最小値に達し、その位置のアトムで消費される文字がなくなると、 数量詞は照合を停止します。 これが `/(a*)*/.exec("b")` が無限ループにならない理由です。

貪欲な数量詞は可能な限り多くの回数の照合をしようとします。例えば、`/(aa|aabaac|ba)*/.exec("aabaac")` は `"aabaac"` の代わりに `"aa"` と `:ba"` に一致します。

数量詞は単一のアトムに適用されます。長いパターンや論理和を量化したい場合は、グループ化する必要があります。 数量詞はアサーションには適用できません。

```js
/^\*/; // SyntaxError: Invalid regular expression: nothing to repeat
```

Unicode 対応モードでは、先読みアサーションは量化できます。これはウェブの互換性のための非推奨構文であり、頼ってはいけません。

```js
/(?=a)?b/.test("b"); // true; 先読みが 0 回一致
```

例
-

### HTML タグの除去

次の例は、山括弧で囲まれた HTML タグを除去します。消費する文字が多くなりすぎないように `?` を使用していることに注意してください。

```js
function stripTags(str) {
  return str.replace(/<.+?>/g, "");
}

stripTags("<p><em>lorem</em> <strong>ipsum</strong></p>"); // 'lorem ipsum'
```

貪欲な照合でも同じ効果が得られますが、繰り返されるパターンが `>` に一致しません。

```js
function stripTags(str) {
  return str.replace(/<[^>]+>/g, "");
}

stripTags("<p><em>lorem</em> <strong>ipsum</strong></p>"); // 'lorem ipsum'
```

**警告:** これはデモのためのもので、属性値の中に `>` がある場合は正しく扱えません。代わりに適切な HTML サニタイザー、たとえば HTML サニタイザー API などを使用してください。

### Markdown の段落の位置を指定

Markdown では、段落は 1 つ以上の空白行で区切られます。次の例では、2 つ以上の改行と照合することで、文字列内のすべての段落を数えます。

```js
function countParagraphs(str) {
  return str.match(/(?:\r?\n){2,}/g).length + 1;
}

countParagraphs(`
Paragraph 1

Paragraph 2
Containing some line breaks, but still the same paragraph

Another paragraph
`); // 3
```

**警告:** これはデモのためのもので、コードブロック内の改行や、見出しのような他の Markdown ブロック要素を処理しません。代わりに適切な Markdown パーサーを使用してください。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-Quantifier |

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

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

関連情報
----

* 数量詞
* 正規表現リファレンス
* 論理和: `|`
* 文字クラス: `[...]`, `[^...]`


ワイルドカード: . - JavaScript

ワイルドカード: .
==========

**ワイルドカード**は改行文字を除くすべての文字に一致します。`s` フラグが設定された場合は、改行文字にも一致します。

構文
--

```regex
.
```

解説
--

`.` は改行文字を除くあらゆる文字に一致します。`s` フラグが設定された場合、`.` は改行文字にも一致します。

`.` に一致する正確な文字の集合は、正規用言が Unicode 対応モードであるかによります。Unicode 対応モードでは、`.` はあらゆる Unicode コードポイントに一致します。それ以外の場合は、あらゆる UTF-16 コード単位に一致します。例えば次のようになります。

```js
/../.test("😄"); // true。サロゲートペアとして 2 つの UTF-16 コード単位に一致します。
/../u.test("😄"); // false。1 つの Unicode 文字しかありません。
```

例
-

### 数量詞の使用

ワイルドカードはしばしば数量詞と共に使用され、次に関心がある文字が得られるまで、任意の文字列に一致します。 例えば、次の例では Markdown ページのタイトルを `# Title` という形で抽出します。

```js
function parseTitle(entry) {
  // タイトルがファイルの始めにはない可能性があるので、複数行モードを使用する。
  // m フラグは . を行末に一致させないので、タイトルは単一の行になければ
  // ならないことに注意する
  // 最初のキャプチャグループに一致したテキストを返す。
  return /^#[ \t]+(.+)$/m.exec(entry)?.[1];
}

parseTitle("# Hello world"); // "Hello world"
parseTitle("## Subsection"); // undefined
parseTitle(`
---
slug: Web/JavaScript/Reference/Regular\_expressions/Wildcard
---

# Wildcard: .

A \*\*wildcard\*\* matches all characters except line terminators.
`); // "Wildcard: ."
```

### コードブロックのコンテンツの照合

次の例は Markdown の 3 つのバックスティックで囲まれたコードブロックの内容に一致します。コードブロックの内容が複数行にまたがる可能性があるため、`.` を改行と一致させるために `s` フラグを使用しています。

```js
function parseCodeBlock(entry) {
  return /^```.\*?^(.+?)\n```/ms.exec(entry)?.[1];
}

parseCodeBlock(`
\`\`\`js
console.log("Hello world");
\`\`\`
`); // "console.log("Hello world");"

parseCodeBlock(`
A \`try...catch\` statement must have the blocks enclosed in curly braces.

\`\`\`js-nolint example-bad
try
 doSomething();
catch (e)
 console.log(e);
\`\`\`
`); // "try\n doSomething();\ncatch (e)\n console.log(e);"
```

**警告:** この例はあくまでデモンストレーションのためのものです。 Markdown を解析したい場合は、考慮すべきエッジケースがたくさんあるため、専用の Markdown パーサーを使用してください。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-Atom |

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

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

関連情報
----

* 文字クラス
* 正規表現リファレンス
* 文字クラス: `[...]`, `[^...]`
* 文字クラスエスケープ: `\d`, `\D`, `\w`, `\W`, `\s`, `\S`


名前付きキャプチャグループ: (?<name>...) - JavaScript

名前付きキャプチャグループ: (?<name>...)
===========================

**名前付きキャプチャグループ**は特定の種類のキャプチャグループで、グループに名前を付けることができます。グループの照合結果は、パターン内のインデックスではなく、この名前で後で識別することができます。

構文
--

```regex
(?<name>pattern)
```

### 引数

`pattern`

正規表現リテラルで使用することができるあらゆるものから成るパターンで、論理和を含みます。

`name`

グループの名前です。有効な識別子である必要があります。

解説
--

名前付きキャプチャグループは、キャプチャグループと同様に使用することができます 。結果の配列の一致インデックスも持っており、`\1`、`\2` などによって参照することができます。唯一の違いは、名前によって「追加的に」参照することができるということです。 キャプチャグループの一致する情報には、以下のようにしてアクセスすることができます。

* `RegExp.prototype.exec()`、`String.prototype.match()`、`String.prototype.matchAll()` の返値の `groups` プロパティ
* `String.prototype.replace()` および `String.prototype.replaceAll()` メソッドの `replacement` コールバック関数の `groups` 引数
* 同じパターン内の名前付き後方参照

同じパターン内は、すべての名前が一意でなければなりません。同じ名前を持つ複数の名前付きキャプチャグループは構文エラーとなります。

```js
/(?<name>)(?<name>)/; // SyntaxError: Invalid regular expression: Duplicate capture group name
```

重複する名前付きキャプチャグループが同じ論理和の選択肢にない場合、この制限は緩和されますので、どのような文字列入力に対しても、実際に一致できる名前付きキャプチャグループは 1 つだけです。これはかなり新しい機能なので、使う前にブラウザーの互換性をチェックしてください。

```js
/(?<year>\d{4})-\d{2}|\d{2}-(?<year>\d{4})/;
// 動作します。"year" をハイフンの前にも後にも置くことができます
```

結果の中に、名前付きキャプチャグループはすべて存在します。名前付きキャプチャグループが一致していない場合（例えば、論理和で一致しない選択肢に属している場合）、`groups` オブジェクトの対応するプロパティは `undefined` の値になります。

```js
/(?<ab>ab)|(?<cd>cd)/.exec("cd").groups; // [Object: null prototype] { ab: undefined, cd: 'cd' }
```

`d` フラグを使用することで、入力文字列中のそれぞれの名前付きキャプチャグループの開始と終わりのインデックスを取得することができます。`exec()` が返す配列の `indices` プロパティで取得することに加えて、`indices.groups` の名前でも取得することができます。

無名キャプチャグループに比べ、名前付きキャプチャグループには以下のような利点があります。

* 個々の部分一致の結果に説明的な名前を提供することができます。
* これにより、パターンに現れる順番を覚えておくことなく、部分一致の結果にアクセスすることができます。
* コードをリファクタリングするとき、他の参照を壊す心配をすることなく、キャプチャグループの順序を変更することができます。
例
-

### 名前付きキャプチャグループの使用

次の例は、Git のログ項目（`git log --format=%ct,%an -- filename` の出力）からタイムスタンプと作者名を解析します。

```js
function parseLog(entry) {
  const { author, timestamp } = /^(?<timestamp>\d+),(?<author>.+)$/.exec(
    entry,
  ).groups;
  return `${author} committed on ${new Date(
 parseInt(timestamp) \* 1000,
 ).toLocaleString()}`;
}

parseLog("1560979912,Caroline"); // "Caroline committed on 6/19/2019, 5:31:52 PM"
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-Atom |

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

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

関連情報
----

* 名前付きキャプチャグループのポリフィル (`core-js`)
* グループと後方参照
* 正規表現リファレンス
* キャプチャグループ: `(...)`
* 非キャプチャグループ: `(?:...)`
* 名前付き後方参照: `\k<name>`
* ESLint rule: `prefer-named-capture-group`


文字クラス: [...], [^...] - JavaScript

文字クラス: [...], [^...]
====================

**文字クラス**は、独自の文字集合に含まれる、または含まれない文字に一致します。`v` フラグを有効にすると、可変長のの文字列にも使用することができます。

構文
--

```regex
[]
[abc]
[A-Z]

[^]
[^abc]
[^A-Z]

// `v` モードのみ
[operand1&&operand2]
[operand1--operand2]
[\q{substring}]
```

### 引数

`operand1`, `operand2`

単一の文字、他の角括弧で囲まれた文字クラス、文字クラスエスケープ、Unicode 文字クラスエスケープ、または `\q` 構文を使用した文字列の何れかをとることができます。

`substring`

リテラル文字列です。

解説
--

文字クラスは角括弧で囲まれた文字のリストを指定し、リスト内の任意の文字と照合します。 `v` フラグは、文字クラスの解釈方法を大きく変えます。以下の構文は `v` モードでも `v` モードでなくても使用できます。

* 単一の文字: その文字自体に一致します。
* 文字の範囲: その範囲のいずれかの文字に一致します。範囲はダッシュ (`-`) で区切られた 2 文字で指定します。最初の文字は、2 つ目の文字よりも文字値が小さくなければなりません。文字値はこの文字の Unicode コードポイントです。Unicode コードポイントは通常アルファベット順に割り当てるので、`[a-z]` はすべて小文字のラテン文字を指定し、`[α-ω]` はすべて小文字のギリシャ文字を指定します。Unicode 非対応モードでは、正規表現は BMP 文字の並びとして解釈されます。したがって、文字クラスのサロゲートペアは 1 文字ではなく 2 文字を表します。詳細は下記を参照してください。
* エスケープシーケンス: `\b`、`\-`、文字クラスエスケープ、Unicode 文字クラスエスケープ、その他の文字エスケープ。

これらの構文は何回でも使うことができ、それらが表す文字集合は結合されます。例えば、`/[a-zA-Z0-9]/` は任意の文字や数字に一致します。

文字クラスの接頭辞 `^` は「補集合クラス」を作成します。例えば、`[^abc]` は `a`、`b`、`c` 以外の文字に一致します。`^` の文字は文字クラスの途中に現れた場合はリテラル文字になります。例えば、 `[a^b]` は `a`、`^`、`b` に一致します。

字句文法は正規表現リテラルをとても寛容に解釈し、文字クラス内に現れる `/` 文字で正規表現リテラルが終わらないようにします。これは `/[/]/` が `/` をエスケープしなくても有効であることを意味しています。

文字範囲の境界に複数の文字を指定することはできません。これは文字クラスのエスケープを使用した場合に起こります。例えば次のようなものです。

```js
/[\s-9]/u; // SyntaxError: Invalid regular expression: Invalid character class
```

Unicode 非対応モードでは、1 つの境界が文字クラスである文字範囲は、`-` がリテラル文字になります。これはウェブの互換性のために非推奨です。

```js
/[\s-9]/.test("-"); // true
```

Unicode 非対応モードでは、正規表現は BMP 文字列として解釈されます。そのため、文字クラスのサロゲートペアは 1 文字ではなく 2 文字を表します。

```js
/[😄]/.test("\ud83d"); // true
/[😄]/u.test("\ud83d"); // false

/[😄-😛]/.test("😑"); // SyntaxError: Invalid regular expression: /[😄-😛]/: Range out of order in character class
/[😄-😛]/u.test("😑"); // true
```

パターンが大文字小文字を無視する場合でも、範囲の両端の大文字小文字は、どの文字がその範囲に属するかを決定する上で重要です。例えば、パターン `/[E-F]/i` は `E`、`F`、`e`、`f` にのみ一致しますが、パターン `/[E-f]/i` はすべての大文字と小文字の ASCII 文字（`E–Z` と `a–f` にまたがるため）、および `[`、`\`、`]`、`^`、`_`、``` に一致します。

### v モードでない場合の文字クラス

`v` モードでない場合の文字クラスは、ほとんどの文字を文字通りに解釈し、格納する文字に関する制限はあまりありません。例えば、`.` はワイルドカードではなく、ドット文字のリテラルです。文字通りに現れることができない文字は、`\`、`]`、`-` だけです。

* 文字クラスでは、`\b`、`\B`、後方参照を除き、ほとんどのエスケープシーケンスに対応しています。`\b` は単語境界の代わりにバックスペース文字を示し、他の 2 種類は構文エラーが発生します。`\` をリテラルとして使用して使用するには、`\\` とエスケープしてください。
* `]` 文字は文字クラスの終わりを示します。リテラルとして使用するには、`\]` とエスケープしてください。
* ダッシュ (`-`) 文字は、2 つの文字の間に使用すると範囲を示します。文字クラスの先頭や末尾に現れる場合は、リテラル文字です。範囲の境界で使用する場合もリテラル文字です。例えば、`[a-]` は `a` と `-` に一致し、`[!--]` は `!` から `-` に一致し、`[--9]` は `-` から `9` に一致します。また、文字どおり任意の場所で使用したい場合は、`\-` でエスケープすることもできます。
### v モード文字クラス

`v` モードでは文字クラスの基本的な考え方は変わりません。ほとんどの文字をリテラルを使用して、`-` を使用して文字範囲を表し、エスケープシーケンスを使用することができます。`v` フラグの最も重要な機能の 1 つは、文字クラス内での「セット表記」です。前回述べたように、通常の文字クラスは 2 つの範囲を連結することで論理和を発生させることができます。例えば、`[A-Z0-9]` を使用して「集合 `[A-Z]` と集合 `[0-9]` の論理和」を意味しています。しかし、交差や差のような文字集合を使った他の処理を表す簡単な方法はありません。

`v` フラグを使うと、交差は `&&` で表現され、差集合は `--` で表現されます。どちらもない場合は論理和となります。または `--` の 2 つのオペランドは文字、文字エスケープ、文字クラスエスケープ、別の文字クラスのいずれかを取ることができます。例えば、「アンダースコアでない単語文字」を表すには `[ \w--_]` を使うことができます。同じレベルの演算子を混合することはできません。例えば、`[\w&&[A-z]--_]` は構文エラーになります。しかし、文字クラスは入れ子にすることができるので、`[\w&&[[A-z]--_]]` や `[[\w&&[A-z]]--_]`（どちらも `[A-Za-z]` を意味している）と書くことで明示的にすることができます。同様に、`[AB--C]` は無効なので、`[A[B--C]]`（これは単に `[AB]` を意味している）と書く必要があります。

`v` モードでは、Unicode 文字クラスエスケープ `\p` は、絵文字のような可変長の文字列と一致させることができます。対称性のために、通常の文字クラスも複数の文字に一致することができます。文字クラスで「文字列リテラル」を書くには、その文字列を `\q{...}` で囲みます。ここで対応している正規表現構文は論理和のみです。それとは別に、`\q` で完全にリテラル（エスケープ文字を含む）を囲む必要があります。これにより、文字クラスは有限個の可能性を持つ可変長文字列にのみ一致することを保証します。

文字クラスの構文がより洗練されるようになり、より多くの文字が予約され、文字通りに現れることが禁止されます。

* `]` と `\` に加え、`(`、`)`、`[`、`{`、`}`、`/`、`-`、`|` の文字は、文字クラス内で文字通りに表わす場合、エスケープする必要があります。このリストは構文文字のリストと多少似ていますが、`^`、`$`、`*`、`+`、`?` は文字クラス内部では予約されておらず、`/` と `-` は文字クラス外部では予約されていません（`/` は正規表現リテラルを区切り文字とする可能性があるため、エスケープする必要がありますが）。これらの文字はすべて、オプションで `u` モード文字クラスでもエスケープできます。
* 「二重区切り記号」シーケンス、`&&`、`!!`、`##`、`$$`、`%%`、`**`、`++`、`,,`、`..`、`::`、`;;`、`<<`、`==`、`>>`、`??`、`@@`、`^^`、````、`~~` も同様にエスケープする必要があります（ただし、`v` フラグがないとあまり意味がありません）。`u` モードでは、これらの文字のいくつかは文字クラス内にしか現れず、エスケープすると構文エラーが発生します。`v` モードでは、ペアで現れる場合はエスケープしなければなりませんが、単独で現れる場合はオプションでエスケープすることができます。例えば、`/[\!]/u` は識別エスケープなので無効ですが、`/[\!]/v` と `/[!]/v` の両方は有効で、`/[!!]/v` は無効です。リテラル文字参照には、どの文字がエスケープまたはアンエスケープされて現れるかの詳細な表があります。

補集合文字クラス `[^...]` は 1 文字より長い文字列と一致することはできません。 例えば、`[\q{ab|c}]` は有効で文字列 `"ab"` と一致しますが、`[^\q{ab|c}]` は何文字が消費されるかが不明なので無効です。このチェックは、すべての `\q` が単一の文字を格納し、すべての `\p` が文字プロパティを指定しているかどうかを調べることで行われます。和集合の場合、オペランドはすべて純粋な文字でなければなりません。交差の場合、少なくとも 1 つのオペランドは純粋な文字でなければなりません。差集合の場合、左端のオペランドは純粋な文字でなければなりません。つまり、`/[^q{ab|c}--q{ab}]/v` は `/[^c]/v` と等価ですが、拒否されます。

### 補集合クラスと大文字小文字を区別しない照合

`v` モードでない場合、補集合文字クラス `[^...]` は単純に照合結果を反転させるものとして実装されています。つまり、`[...]` が一致しない場合は常に `[^...]` が一致し、その逆も同様です。しかし、`\P{...}` や `\W` のような他の補集合クラスは、指定したプロパティを持たないすべての文字からなる集合を独自に設定することで動作します。これらは同じ動作をするように見えますが、大文字と小文字を区別する照合と一致するとより複雑になります。

以下の 2 つの正規表現を考えてみましょう。

```js
const r1 = /\p{Lowercase\_Letter}/iu;
const r2 = /[^\P{Lowercase\_Letter}]/iu;
```

`r2` は二重否定で、`r1` と等価のように見えます。しかし、実際には `r1` は小文字と大文字の ASCII 文字すべてに一致しますが、`r2` は一致しません。どのように動作するのかを説明するために、Unicode 文字集合全体ではなく、ASCII 文字だけを扱っていると仮定し、`r1` と `r2` を下記のように指定してみましょう。

```js
const r1 = /[a-z]/iu;
const r2 = /[^A-Z]/iu;
```

大文字小文字を区別しない照合は、パターンと入力を同じ大文字小文字に変換することによって行われます（詳細は `ignoreCase` を参照してください）。`r1` の場合、文字クラス `a-z` は大文字小文字を区別した後も同じままですが、大文字と小文字の ASCII 文字列の入力は小文字に変換されるので、 `r1` は `"A"` と `"a"` の両方に一致することができます。`r2` の場合、文字クラス `A-Z` は `a-z` に変換されますが、`^` は照合結果を否定するので、実質的に `[^A-Z]` は大文字の文字列にのみ一致します。しかし、大文字と小文字の ASCII 文字列の入力は小文字に変換されたままなので、`r2` は何にも一致しません。

`v` モードでは、この動作は修正されました。`[^...]` も一致した結果を否定する代わりに、補集合クラスを貪欲に構築します。これにより、`[^\P{Lowercase_Letter}]` と `\p{Lowercase_Letter}` は厳密に等価になります。

例
-

### 16 進数の桁との照合

次の関数は、文字列が有効な 16 進数を格納しているかどうかを判定します。

```js
function isHexadecimal(str) {
  return /^[0-9A-F]+$/i.test(str);
}

isHexadecimal("2F3"); // true
isHexadecimal("beef"); // true
isHexadecimal("undefined"); // false
```

### 交差の使用

次の関数はギリシャ語の文字に一致します。

```js
function greekLetters(str) {
  return str.match(/[\p{Script\_Extensions=Greek}&&\p{Letter}]/gv);
}

// 𐆊 is U+1018A GREEK ZERO SIGN
greekLetters("π𐆊P0零αAΣ"); // [ 'π', 'α', 'Σ' ]
```

### 差集合の使用

以下の関数は、非 ASCII の数字に一致します。

```js
function nonASCIINumbers(str) {
  return str.match(/[\p{Decimal\_Number}--[0-9]]/gv);
}

// 𑜹 is U+11739 AHOM DIGIT NINE
nonASCIINumbers("𐆊0零1𝟜𑜹a"); // [ '𝟜', '𑜹' ]
```

### 文字列の照合

以下の関数は、改行文字や `\r\n` (CRLF) シーケンスを含むすべての行末シーケンスに一致します。

```js
function getLineTerminators(str) {
  return str.match(/[\r\n\u2028\u2029\q{\r\n}]/gv);
}

getLineTerminators(`
A poem\r
Is split\r\n
Into many
Stanzas
`); // [ '\r', '\r\n', '\n' ]
```

この例は、短いという点を除けば `/(?:\r|\n|\u2028|\u2029|\r\n)/gu` or `/(?:[\r\n\u2028\u2029]|\r\n)/gu` とまったく同じです。

`\q{}` の最も有益な用途は、差分と交差を行う場合です。前回までは複数の先読みで使用可能でした。以下の関数はアメリカ、中国、ロシア、イギリス、フランスのどれでもない国旗に一致します。

```js
function notUNSCPermanentMember(flag) {
  return /^[\p{RGI\_Emoji\_Flag\_Sequence}--\q{🇺🇸|🇨🇳|🇷🇺|🇬🇧|🇫🇷}]$/v.test(flag);
}

notUNSCPermanentMember("🇺🇸"); // false
notUNSCPermanentMember("🇩🇪"); // true
```

この例は、おそらくもっと効率が良いという以外は、`/^(?!🇺🇸|🇨🇳|🇷🇺|🇬🇧|🇫🇷)\p{RGI_Emoji_Flag_Sequence}$/v` とほぼ同じです。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-CharacterClass |

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

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

関連情報
----

* 文字クラス
* 正規表現リファレンス
* 文字クラスエスケープ: `\d`, `\D`, `\w`, `\W`, `\s`, `\S`
* Unicode 文字クラスエスケープ: `\p{...}`, `\P{...}`
* リテラル文字: `a`, `b`
* 文字エスケープ: `\n`, `\u{...}`
* 論理和: `|`
* RegExp v flag with set notation and properties of strings on v8.dev (2022)


非キャプチャグループ: (?:...) - JavaScript

非キャプチャグループ: (?:...)
===================

**非キャプチャグループ**はサブパターンをグループ化し、グループ全体に数量詞を適用したり、グループ内で論理和を使用したりすることができます。これは JavaScript で発生したグループ化演算子のように動作します。キャプチャグループとは異なり、一致したテキストを記憶しないため、パフォーマンスが向上し、パターンが有用なキャプチャグループを含む場合の混乱を避けることができます。

構文
--

```regex
(?:pattern)
```

### 引数

`pattern`

正規表現リテラルで使用できるあらゆるものからなるパターンで、論理和も含まれます。

例
-

### サブパターンのグループ化と数量詞の適用

以下の例では、ファイルパスの末尾が `styles.css` か `styles.[a hex hash].css` かを検査します。`\.[\da-f]+` の部分全体はオプションであるため、これに `?` 量子化子を適用するには、これを新しいアトムにグループ化する必要があります。 非キャプチャグループを使用すると、必要のない余分な一致情報を生成しないため、パフォーマンスが向上します。

```js
function isStylesheet(path) {
  return /styles(?:\.[\da-f]+)?\.css$/.test(path);
}

isStylesheet("styles.css"); // true
isStylesheet("styles.1234.css"); // true
isStylesheet("styles.cafe.css"); // true
isStylesheet("styles.1234.min.css"); // false
```

### 論理和のグループ化

論理和は正規表現では最も優先順位が低くなります。 大きなパターンの一部として論理和を使いたい場合は、グループ化する必要があります。 論理和の一致したテキストに依存しない限り、非キャプチャグループを使うことをお勧めします。 次の例は、入力境界アサーションの記事と同じコードで、ファイルの拡張子に一致します。

```js
function isImage(filename) {
  return /\.(?:png|jpe?g|webp|avif|gif)$/i.test(filename);
}

isImage("image.png"); // true
isImage("image.jpg"); // true
isImage("image.pdf"); // false
```

### リファクタリング災害の防止

キャプチャグループはパターン内の位置によってアクセスされます。照合結果や後方参照からアクセスしている場合、キャプチャグループを追加または除去すると、他のキャプチャグループの位置も更新する必要があります。 特に、ほとんどのグループが純粋に構文上の目的（数量詞を適用するため、または論理和をグループ化するため）である場合、これはバグの原因となる可能性があります。 非キャプチャグループを使用することで、この問題を避けることができ、実際のキャプチャグループのインデックスを簡単に追跡することができます。

例えば、文字列中の `title='xxx'` というパターンと照合する関数があるとします（キャプチャグループから引用した例）。 引用符が確実に一致するように、後方参照を使って最初の引用符を参照しています。

```js
function parseTitle(metastring) {
  return metastring.match(/title=(["'])(.\*?)\1/)[2];
}

parseTitle('title="foo"'); // 'foo'
```

後で `name='xxx'` を `title=` の別名として追加することにした場合、別のグループに論理和をグループ化する必要があります。

```js
function parseTitle(metastring) {
  // おっと — 後方参照とインデックスアクセスが 1 つずつずれてしまいました
  return metastring.match(/(title|name)=(["'])(.\*?)\1/)[2];
}

parseTitle('name="foo"'); // null のプロパティが読めない (reading '2')
// \1 が "name" という文字列を指すようになったため、末尾が見つからない
```

キャプチャグループのインデックスを参照している場所をすべて探し出して 1 つ 1 つ更新するのではなく、キャプチャグループを使用しない方が良いでしょう。

```js
function parseTitle(metastring) {
  // 値を使用しないので、title|name の論理和はキャプチャしない
  return metastring.match(/(?:title|name)=(["'])(.\*?)\1/)[2];
}

parseTitle('name="foo"'); // 'foo'
```

名前付きキャプチャグループはリファクタリング災害を避けるためのもう一つの方法です。これにより、他のキャプチャグループが追加または削除されても影響を受けない、独自の名前でキャプチャグループにアクセスできるようになります。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-Atom |

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

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

関連情報
----

* グループと後方参照
* 正規表現リファレンス
* キャプチャグループ: `(...)`
* 名前付きキャプチャグループ: `(?<name>...)`


先読みアサーション: (?=...), (?!...) - JavaScript

先読みアサーション: (?=...), (?!...)
===========================

**先読みアサーション**の「先読み」とは、それ以降の入力を指定されたパターンに照合しようとしますが、入力を消費することはありません。照合に成功した場合、入力の現在の位置はそのままです。

構文
--

```regex
(?=pattern)
(?!pattern)
```

### 引数

`pattern`

論理和を含む、正規表現リテラルで使用することができるあらゆるもので構成されるパターンです。

解説
--

正規表現は一般に左から右に照合します。これが先読みおよび後読みアサーションがこのように呼ばれる理由です。先読みアサーションは右にあるもの、後読みアサーションは左にあるものを表します。

`(?=pattern)` アサーションが成功するためには、`pattern` が現在の位置以降のテキストと一致しなければなりませんが、現在の位置は変化しません。`(?!pattern)` 形式はアサーションを否定します。`pattern` が現在の位置で一致しない場合に成功します。

`pattern` にはキャプチャグループを含めることができます。この場合の動作については、キャプチャグループのページをご覧ください。

他の正規表現演算子とは異なり、先読みへのバックトラックはありません。この動作は Perl から継承されています。これは、`pattern` がキャプチャグループを含み、先読みに続くパターンがそれらのキャプチャへの後方参照を含む場合にのみ問題になります。例えば、次のようになります。

```js
/(?=(a+))a\*b\1/.exec("baabac"); // ['aba', 'a']
// Not ['aaba', 'a']
```

上記のパターンの照合は以下のように行われます。

1. `(a+)` は `"baabac"` の最初の `"a"` の前に成功し、量化詞は貪欲なので `"aa"` が捕捉されます。
2. `a*b` は `"baabac"` の `"aab"` に一致します。
3. `\1` は続く文字列に一致しません。これは 2 つの `"a"` が必要ですが、1 つしか利用できないからです。照合はバックトラックしますが、先読みには入らないので、キャプチャグループを 1 つの `"a"` に縮小することはできず、この点で照合は失敗します。
4. `exec()` は次の位置、つまり 2 番目の `"a"` の前で照合を再試行します。今度は、先読みが `"a"` に一致し、 `a*b` が `"ab"` に一致します。後方参照 `1` はキャプチャされた `"a"` に一致し、照合は成功します。

 もし正規表現が先読みをバックトラックして、そこで行われた選択を修正することができれば、照合は手順 3 で `(a+)` が最初の `"a"` に一致し（最初の 2 つの `"a"` の代わりに）、`a*b` が `"aab"` に一致
 することで、次の入力位置を再試行することなく成功するでしょう。

否定先読みにもキャプチャグループを入れることができますが、後方参照が意味を持つのは `pattern` 内だけです。照合を続けると、必然的に `pattern` は一致しなくなるからです（そうでなければアサーションは失敗します）。この意味は `pattern` の外では、否定先読みのキャプチャグループへの後方参照は常に成功するということです。例えば、次のようになります。

```js
/(.\*?)a(?!(a+)b\2c)\2(.\*)/.exec("baaabaac"); // ['baaabaac', 'ba', undefined, 'abaac']
```

上記のパターンの照合は以下のように行われます。

1. `(.*?)` パターンは貪欲ではないので、何も照合しないことから始まります。しかし、次の文字は `a` で、入力中の `"b"` には一致しません。
2. `(.*?)` パターンは `"b"` に一致するので、パターン中の `a` は `"baaabaac"` の最初の `"a"` に一致します。
3. もし `(a+)` が `"aa"` に一致するならば、`(a+)b2c` は `"aabaac"` に一致します。このため、アサーションは失敗し、マッチャーは後退します。
4. `(.*?)` パターン は`"ba"` に一致するので、パターン中の `a` は `"baaabaac"` の 2 つ目の `"a"` に一致します。
5. この位置では、先読みは照合に失敗します。 なぜなら、残りの入力は「任意の数の `"a"` と `"b"`, 同じ数の `"a"` と `c`」というパターンに続かないからです。これにより、アサーションは成功します。
6. しかし、アサーション内では何も一致しなかったので、後方参照 `\2` には値がなく、空文字列に一致します。そのため、入力の残りの部分は最後の `(.*)` によって消費されます。

通常、アサーションは量化できません。しかし、Unicode 非対応モードにおいては、先読みアサーションは量化することができます。これはウェブの互換性のための非推奨構文としてのみ認められており、頼ってはいけません。

```js
/(?=a)?b/.test("b"); // true; the lookahead is matched 0 time
```

例
-

### 消費せずに文字列を照合

一致した文字列の後に何かが続いていることを、結果として返さずに検証するのが便利なこともあります。次の例は、カンマやピリオドが続く文字列に一致しますが、句読点は結果に含まれません。

```js
function getFirstSubsentence(str) {
  return /^.\*?(?=[,.])/.exec(str)?.[0];
}

getFirstSubsentence("Hello, world!"); // "Hello"
getFirstSubsentence("Thank you."); // "Thank you"
```

興味のある部分一致をキャプチャすることで、同様の効果が得られます。

### パターンの差集合および交差集合

先読みを用いることで、文字列を異なるパターンで複数回照合することができます。これにより、差集合（X であるが Y ではない）や交差集合（X と Y の両方である）といった複雑な関係を発生させることができます。

以下の例は、識別子であり、予約語でないものに一致します（ここでは簡潔にするために 3 つの予約語のみを示しています。この論理和には、さらに予約語を加えることができます。`[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*` という構文は、言語依存の識別子文字列の集合を正確に記述しています。詳しくは、識別子については字句文法を、`\p` エスケープについては Unicode 文字クラスエスケープを参照してください。

```js
function isValidIdentifierName(str) {
  const re =
    /^(?!(?:break|case|catch)$)[$\_\p{ID\_Start}][$\u200c\u200d\p{ID\_Continue}]\*$/u;
  return re.test(str);
}

isValidIdentifierName("break"); // false
isValidIdentifierName("foo"); // true
isValidIdentifierName("cases"); // true
```

次の例は、ASCIIで、かつ識別子部分として使用できる文字列に一致します。

```js
function isASCIIIDPart(char) {
  return /^(?=\p{ASCII}$)\p{ID\_Start}$/u.test(char);
}

isASCIIIDPart("a"); // true
isASCIIIDPart("α"); // false
isASCIIIDPart(":"); // false
```

文字数の有限な交差集合や差集合を扱う場合は、`v` フラグを使用して有効にした文字集合交差構文を使用するとよいでしょう。

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-Assertion |

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

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

関連情報
----

* アサーション
* 正規表現リファレンス
* 入力境界アサーション: `^`, `$`
* 単語境界アサーション: `\b`, `\B`
* 後読みアサーション: `(?<=...)`, `(?<!...)`
* キャプチャグループ: `(...)`