diff options
Diffstat (limited to 'files/ja/web/javascript/guide')
67 files changed, 11785 insertions, 0 deletions
diff --git a/files/ja/web/javascript/guide/class-based_vs._prototype-based_languages/index.html b/files/ja/web/javascript/guide/class-based_vs._prototype-based_languages/index.html new file mode 100644 index 0000000000..800f222ea4 --- /dev/null +++ b/files/ja/web/javascript/guide/class-based_vs._prototype-based_languages/index.html @@ -0,0 +1,25 @@ +--- +title: Class-Based vs. Prototype-Based Languages +slug: Web/JavaScript/Guide/Class-Based_vs._Prototype-Based_Languages +--- +<h3 id=".E3.82.AF.E3.83.A9.E3.82.B9.E3.83.99.E3.83.BC.E3.82.B9.E8.A8.80.E8.AA.9E.E3.81.A8.E3.83.97.E3.83.AD.E3.83.88.E3.82.BF.E3.82.A4.E3.83.97.E3.83.99.E3.83.BC.E3.82.B9.E8.A8.80.E8.AA.9E" name=".E3.82.AF.E3.83.A9.E3.82.B9.E3.83.99.E3.83.BC.E3.82.B9.E8.A8.80.E8.AA.9E.E3.81.A8.E3.83.97.E3.83.AD.E3.83.88.E3.82.BF.E3.82.A4.E3.83.97.E3.83.99.E3.83.BC.E3.82.B9.E8.A8.80.E8.AA.9E">クラスベース言語とプロトタイプベース言語</h3> +<p>Java や C++ といったクラスベースのオブジェクト指向言語はクラスとインスタンスという 2 つの異なる実体があるという概念に基づいています。</p> +<ul> <li>クラスはあるオブジェクトの集合を特徴付けるすべてのプロパティ(Java ではメソッドとフィールドを、C++ ではメンバをプロパティと見なす)を定義する。クラスとはそれが表すオブジェクトの集合の特定のメンバではなく、抽象的なものである。例えば、Employee クラスで従業員すべてを含む集合を表す。</li> <li>一方、インスタンスはクラスを実例にしたものである。つまり、そのメンバの 1 つということである。例えば、Victoria は Employee クラスのインスタンスとなることができる。このクラスは特定の個人を従業者として表すものである。インスタンスはその親クラスのプロパティを正確に保持する(それに他ならない)。</li> +</ul> +<p>JavaScript のようなプロトタイプベース言語はこの区別がありません。単にオブジェクトがあるだけです。プロトタイプベース言語には原型的なオブジェクトという概念があります。このオブジェクトは新しいオブジェクトの初期プロパティを取得する元になるテンプレートとして使用されます。どのオブジェクトもそれ独自のプロパティを指定できます。オブジェクト作成時にも実行時にも可能です。さらに、どのオブジェクトも別のオブジェクトに対するプロトタイプとして関連付けることができます。2 つ目のオブジェクトが 1 つ目のオブジェクトのプロトタイプを共有するということもできます。</p> +<h4 id=".E3.82.AF.E3.83.A9.E3.82.B9.E3.81.AE.E5.AE.9A.E7.BE.A9" name=".E3.82.AF.E3.83.A9.E3.82.B9.E3.81.AE.E5.AE.9A.E7.BE.A9">クラスの定義</h4> +<p>クラスベース言語ではクラス定義ごとにクラスを定義します。定義では特殊なメソッドを指定してそのクラスのインスタンスを作成することができます。そのようなメソッドはコンストラクタと呼びます。コンストラクタメソッドはインスタンスのプロパティに対する初期値を指定することができます。また、作成時に他の適当な処理を実行することもできます。new 演算子をコンストラクタメソッドと一緒に用いることでクラスのインスタンスを作成できます。</p> +<p>JavaScript は同様のモデルに従っていますが、コンストラクタと別になっているクラス定義がありません。その代わりに、プロパティと値からなる特定の初期的なセットを持つオブジェクトを作成するコンストラクタ関数を定義します。どの JavaScript 関数もコンストラクタとして使用できます。new 演算子をコンストラクタ関数とともに使用することで新しいオブジェクトを作成します。</p> +<h4 id=".E3.82.B5.E3.83.96.E3.82.AF.E3.83.A9.E3.82.B9.E3.81.A8.E7.B6.99.E6.89.BF" name=".E3.82.B5.E3.83.96.E3.82.AF.E3.83.A9.E3.82.B9.E3.81.A8.E7.B6.99.E6.89.BF">サブクラスと継承</h4> +<p>クラスベース言語ではクラス定義を通じてクラスの階層を作ります。クラス定義では新しいクラスがある既存のクラスのサブクラスになるように指定することができます。サブクラスはスーパークラスの全プロパティを継承します。さらに新しくプロパティを追加したり継承したものを変更することもできます。例えば、Employee クラスが name および dept プロパティのみを含んでおり、Manager は reports プロパティを追加する Employee のサブクラスであるとします。この場合、Manager クラスのインスタンスは name、dept、reports という 3 つのプロパティをすべて持つことになります。</p> +<p>JavaScript では、原型的なオブジェクトをどのコンストラクタ関数にも結びつけることができるようにして継承を実装しています。そのため、全く同じような Employee と Manager の例を作成することができますが、使用する用語が若干異なります。まず、Employee コンストラクタ関数を定義します。これは name および dept プロパティを指定します。次に Manager コンストラクタ関数を定義します。これは reports プロパティを指定します。最後に新しい Employee オブジェクトを Manager コンストラクタ関数に対するプロトタイプとして代入します。そして新しい Manager を作成すると、このオブジェクトは Employee オブジェクトから name および dept プロパティを継承します。</p> +<h4 id=".E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E8.BF.BD.E5.8A.A0.E3.81.A8.E5.89.8A.E9.99.A4" name=".E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E8.BF.BD.E5.8A.A0.E3.81.A8.E5.89.8A.E9.99.A4">プロパティの追加と削除</h4> +<p>クラスベース言語では一般的にクラスをコンパイル時に生成し、コンパイル時または実行時にクラスのインスタンスを作成します。クラス定義後にそのクラスのプロパティの数や型を変更することはできません。しかし、JavaScript ではどんなオブジェクトでも実行時にプロパティを追加したり削除したりすることができます。あるオブジェクトのセットでプロトタイプとして使用されているオブジェクトにプロパティを追加すると、そのプロトタイプの使用元であるオブジェクトにも新しいプロパティが追加されます。</p> +<h4 id=".E9.81.95.E3.81.84.E3.81.AE.E6.A6.82.E8.A6.81" name=".E9.81.95.E3.81.84.E3.81.AE.E6.A6.82.E8.A6.81">違いの概要</h4> +<p>次の表でこれらの違いをいくつか短くまとめてみます。この章の残りで、JavaScript のコンストラクタとプロトタイプを用いてオブジェクト階層を作成することについての詳細を説明していきます。また、この方法が Java ではどう変わるかという比較もします。</p> +<table class="fullwidth-table"> <tbody> <tr> <th>クラスベース (Java)</th> <th>プロトタイプベース (JavaScript)</th> </tr> <tr> <td>クラスとインスタンスは異なる実体である。</td> <td>すべてのオブジェクトはインスタンスである。</td> </tr> <tr> <td>クラス定義を用いてクラスを定義する。また、コンストラクタメソッドを用いてクラスをインスタンス化する。</td> <td>コンストラクタ関数を用いてオブジェクトのセットを定義し、作成する。</td> </tr> <tr> <td><code>new</code> 演算子を用いて単一のオブジェクトを作成する。</td> <td>同じ。</td> </tr> <tr> <td>既存のクラスのサブクラスを定義するクラス定義を用いてオブジェクト階層を構築する。</td> <td>コンストラクタ関数に結びつけられたプロトタイプとしてオブジェクトを代入することでオブジェクト階層を構築する。</td> </tr> <tr> <td>クラスチェーンに従ってプロパティを継承する。</td> <td>プロトタイプチェーンに従ってプロパティを継承する。</td> </tr> <tr> <td>クラス定義がクラスの全インスタンスの全プロパティを指定する。実行時に動的にプロパティを追加することはできない。</td> <td>コンストラクタ関数またはプロトタイプがプロパティの初期セットを指定する。個々のオブジェクトやオブジェクトの全体のセットに動的にプロパティを追加したり、それらからプロパティを除去したりできる。</td> </tr> </tbody> +</table> +<div class="noinclude"> +<p>{{ PreviousNext("Core_JavaScript_1.5_Guide:Predefined_Core_Objects:String_Object", "Core_JavaScript_1.5_Guide:The_Employee_Example") }}</p> +</div> +<p>{{ languages( { "zh-tw": "zh_tw/Core_JavaScript_1.5_教學/以類別為基礎的語言_vs._以原型為基礎的語言", "en": "en/Core_JavaScript_1.5_Guide/Class-Based_vs._Prototype-Based_Languages", "es": "es/Gu\u00eda_JavaScript_1.5/Lenguajes_basados_en_clases_frente_a_basados_en_prototipos", "fr": "fr/Guide_JavaScript_1.5/Langages_bas\u00e9s_sur_les_classes_et_langages_bas\u00e9s_sur_les_prototypes", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/J\u0119zyki_oparte_na_klasach_vs._oparte_na_prototypach", "zh-cn": "cn/Core_JavaScript_1.5_Guide/Class-Based_vs._Prototype-Based_Languages" } ) }}</p> diff --git a/files/ja/web/javascript/guide/control_flow_and_error_handling/index.html b/files/ja/web/javascript/guide/control_flow_and_error_handling/index.html new file mode 100644 index 0000000000..f9c13b952c --- /dev/null +++ b/files/ja/web/javascript/guide/control_flow_and_error_handling/index.html @@ -0,0 +1,457 @@ +--- +title: 制御フローとエラー処理 +slug: Web/JavaScript/Guide/Control_flow_and_error_handling +tags: + - Beginner + - Decision making + - Error Handling + - Flow control + - Guide + - JavaScript + - Logic + - control + - 'l10n:priority' + - statements +translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling +--- +<p class="summary">{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}</p> + +<p class="summary">JavaScript は、特に制御フロー文についてはコンパクトな文のセットに対応しており、アプリケーションに多様な対話的機能を組み込むために利用することができます。この節ではこれらの文の概要を説明します。</p> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Statements">JavaScript リファレンス</a>には、この章で紹介する文についての完全な詳細が載っています。また、JavaScript のコードではセミコロン (<code>;</code>) 文字で文を区切ります。</p> + +<p>あらゆる JavaScript の式は、文でもあります。式に関する詳細については<a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators">式と演算子</a>を参照ください。</p> + +<h2 id="Block_statement" name="Block_statement">ブロック文</h2> + +<p>最も基本的な文は<dfn>ブロック文</dfn>で、文のグループ化に使います。ブロックは、一組の波括弧で区切られます。</p> + +<pre class="syntaxbox notranslate">{ + <var>statement_1</var>; + <var>statement_2</var>; + ⋮ + <var>statement_n</var>; +} +</pre> + +<h3 id="Example" name="Example">例</h3> + +<p>ブロック文は一般に制御フロー文 (<code>if</code>, <code>for</code>, <code>while</code>) で用いられます。</p> + +<pre class="brush: js notranslate">while (x < 10) { + x++; +} +</pre> + +<p>ここでは <code>{ x++; }</code> がブロック文となります。</p> + +<div class="blockIndicator note"> +<p><strong>重要</strong>: ECMAScript 2015 (6<sup>th</sup> edition) より前の JavaScript にはブロックスコープが<strong>ありません</strong>。古い JavaScript では、ブロック内で導入された変数のスコープは、そのブロックがある関数やスクリプトになり、それらの変数を設定した影響は、そのブロックを越えて持続します。つまり、<em>ブロック文はスコープを定義しない</em>ということです。</p> + +<p>「単独の」ブロックも正しい構文ですが、C や Java のブロックで提供されるものとは異なる結果をもたらします。例えば、</p> + +<pre class="brush: js notranslate">var x = 1; +{ + var x = 2; +} +console.log(x); // 2 を出力 +</pre> + +<p>ここで <code>2</code> が出力されるのは、ブロック内の <code>var x</code> 文がブロックの前の <code>var x</code> 文と同じスコープ内にあるためです。(C や Java では、同様のコードで <code>1</code> が出力されます。)</p> + +<p><strong>ECMAScript 2015 から</strong>は、<code>let</code> 文や <code>const</code> による変数宣言はブロックスコープとなります。詳しくは {{jsxref("Statements/let", "let")}} 文や {{jsxref("Statements/const", "const")}} のリファレンスページをご覧ください。</p> +</div> + +<h2 id="Conditional_statements" name="Conditional_statements">条件文</h2> + +<p>条件文は、指定した条件が true の場合に実行する命令の集まりです。JavaScript は <code>if...else</code> と <code>switch</code> の 2 つの条件文に対応しています。</p> + +<h3 id="if...else_statement" name="if...else_statement"><code>if...else</code> 文</h3> + +<p><code>if</code> を使用すると、論理条件が <code>true</code> の場合に文を実行することができます。任意の <code>else</code> 節を使用すると、条件が <code>false</code> の場合にも文を実行することができます。</p> + +<p><code>if</code> 文は次のように使用します。</p> + +<pre class="syntaxbox notranslate">if (<var>condition</var>) { + <var>statement_1</var>; +} else { + <var>statement_2</var>; +}</pre> + +<p>条件は、<code>true</code> または <code>false</code> と評価される任意の式にすることができます。(<code>true</code> と <code>false</code> の評価の説明については、<a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Boolean#Description">Boolean</a> を参照してください。)</p> + +<p>条件が <code>true</code> と評価された場合、<code><var>statement_1</var></code> が実行されます。そうでなければ、<code><var>statement_2</var></code> が実行されます。<code><var>statement_1</var></code> と <code><var>statement_2</var></code> は、入れ子になった <code>if</code> 文も含めて、任意の文にすることができます。</p> + +<p>以下のように、<code>else if</code> を使用した文を組み合わせて、複数の条件を順番にテストすることもできます。</p> + +<pre class="syntaxbox notranslate">if (<var>condition_1</var>) { + <var>statement_1</var>; +} else if (<var>condition_2</var>) { + <var>statement_2</var>; +} else if (<var>condition_n</var>) { + <var>statement_n</var>; +} else { + <var>statement_last</var>; +} +</pre> + +<p>複数の条件がある場合、<code>true</code> と評価された最初の論理条件のみが実行されます。複数の文を実行するには、ブロックステートメント (<code>{ … }</code>) 内にグループ化します。</p> + +<h4 id="Best_practice" name="Best_practice">ベストプラクティス</h4> + +<p>一般的に、常にブロック文を使用するのが優れた方法です。<em>特に</em> <code>if</code> 文を入れ子にしたコードで有効です。</p> + +<pre class="syntaxbox notranslate">if (<var>condition</var>) { + <var>statement_1_runs_if_condition_is_true</var>; + <var>statement_2_runs_if_condition_is_true</var>; +} else { + <var>statement_3_runs_if_condition_is_false</var>; + <var>statement_4_runs_if_condition_is_false</var>; +} +</pre> + +<p>条件式内で単純な代入を行わないでください。コードを一見した際に、代入を等値条件と見間違えるおそれがあるためです。</p> + +<p>例えば、このようにはコードを<em>書かない</em>でください。</p> + +<pre class="example-bad brush: js notranslate">// "x == y" と読み間違えるおそれがある。 +if (x = y) { + /* ここに文が来る */ +} +</pre> + +<p>条件式で代入を行う必要がある場合、一般的な方法は次のように、代入式をさらに丸括弧でくくることです。</p> + +<pre class="example-good brush: js notranslate">if ((x = y)) { + /* ここに文が来る */ +} +</pre> + +<h4 id="Falsy_values" name="Falsy_values">false と評価される値</h4> + +<p>以下の値は <code>false</code> と評価されます (また、{{Glossary("Falsy")}} な値と呼ばれています)。</p> + +<ul> + <li><code>false</code></li> + <li><code>undefined</code></li> + <li><code>null</code></li> + <li><code>0</code></li> + <li><code>NaN</code></li> + <li>空の文字列 (<code>""</code>)</li> +</ul> + +<p>上記以外の—オブジェクトを含む—すべての値は、条件文に渡されると <code>true</code> と評価されます。</p> + +<div class="blockIndicator note"> +<p><strong>注意:</strong> プリミティブな真偽値の <code>true</code> と <code>false</code> を、{{jsxref("Boolean")}} オブジェクトの true や false という値と混同しないでください。</p> + +<p>例:</p> + +<pre class="brush: js notranslate">var b = new Boolean(false); +if (b) // この条件は true に評価される +if (b == true) // この条件は false に評価される +</pre> +</div> + +<h4 id="Example_2" name="Example_2">例</h4> + +<p>次の例で、関数 <code>checkData</code> は <code>Text</code> オブジェクトに含まれている文字数が 3 である場合に <code>true</code> を返し、そうでない場合はアラートを表示して <code>false</code> を返します。</p> + +<pre class="brush: js notranslate">function checkData() { + if (document.form1.threeChar.value.length == 3) { + return true; + } else { + alert( + 'Enter exactly three characters. ' + + `${document.form1.threeChar.value} is not valid.`); + return false; + } +} +</pre> + +<h3 id="switch_statement" name="switch_statement"><code>switch</code> 文</h3> + +<p><code>switch</code> 文を使うと、プログラムは式を評価し、その式の値を <code>case</code> ラベルと照合します。一致すると、プログラムはそのラベルに関連付けられた文を実行します。</p> + +<p><code>switch</code> 文は次のようになります。</p> + +<pre class="syntaxbox notranslate">switch (<var>expression</var>) { + case <var>label_1</var>: + <var>statements_1</var> + [break;] + case <var>label_2</var>: + <var>statements_2</var> + [break;] + … + default: + <var>statements_def</var> + [break;] +} +</pre> + +<p>JavaScript は上記の switch 文を次のように評価します。</p> + +<ul> + <li>プログラムは最初に、式の値に一致するラベルを持つ <code>case</code> 節を探し、関連付けられた文を実行します。</li> + <li>一致するラベルがない場合、プログラムはオプションの <code>default</code> 節を探します。 + <ul> + <li>存在する場合は <code>default</code> 節に制御を移し、関連付けられた文を実行します。</li> + <li><code>default</code> 節が見つからない場合、プログラムは <code>switch</code> 文の末尾の後に続く文から実行を再開します。</li> + <li>(慣例により、<code>default</code> 節は最後の節に置きますが、そうしなければいけないわけではありません。)</li> + </ul> + </li> +</ul> + +<h4 id="break_statements" name="break_statements">break 文</h4> + +<p>オプションの <code>break</code> 文は、それぞれの <code>case</code> 節と関連付けられ、該当する文が実行されるとプログラムが <code>switch</code> から抜け出し、<code>switch</code> の次の文から実行が継続されることを保証します。<code>break</code> が省略されると、プログラムは <code>switch</code> 文の内部の実行を続けます (そして、次の <code>case</code> を順番に評価します)。</p> + +<h4 id="Example_3" name="Example_3">例</h4> + +<p>次の例では、<code><var>fruittype</var></code> が '<code>Bananas</code>' と評価された場合、case '<code>Bananas</code>' に一致して、それに関連付けら <span class="seoSummary">cv</span> れた文を実行します。<code>break</code> 文に出くわすとプログラムは <code>switch</code> から抜けて、<code>switch</code> の後に続く文を実行します。<code>break</code> を省略すると、<code>case 'Cherries'</code> の文も実行されます。</p> + +<pre class="brush: js notranslate">switch (<var>fruittype</var>) { + case 'Oranges': + console.log('Oranges are $0.59 a pound.'); + break; + case 'Apples': + console.log('Apples are $0.32 a pound.'); + break; + case 'Bananas': + console.log('Bananas are $0.48 a pound.'); + break; + case 'Cherries': + console.log('Cherries are $3.00 a pound.'); + break; + case 'Mangoes': + console.log('Mangoes are $0.56 a pound.'); + break; + case 'Papayas': + console.log('Mangoes and papayas are $2.79 a pound.'); + break; + default: + console.log(`Sorry, we are out of ${fruittype}.`); +} +console.log("Is there anything else you'd like?");</pre> + +<h2 id="Exception_handling_statements" name="Exception_handling_statements">例外処理文</h2> + +<p><code>throw</code> 文を使用して例外を発生させ、<code>try...catch</code> 文を使用して例外を処理することができます。</p> + +<ul> + <li><a href="#throw_statement"><code>throw</code> 文</a></li> + <li><a href="#try...catch_statement"><code>try...catch</code> 文</a></li> +</ul> + +<h3 id="Exception_types" name="Exception_types">例外の型</h3> + +<p>JavaScript では、ほぼどのようなオブジェクトでも例外として投げることができます。とはいえ、必ずしも投げられるオブジェクトすべてが同等に作られているわけではありません。数値や文字列をエラーとして投げる方法がよく用いられますが、こうした用途のために特別に作られた例外データ型を使用した方がより効率的な場合もあります。</p> + +<ul> + <li><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects#Fundamental_objects">ECMAScript 例外</a></li> + <li>{{domxref("DOMException")}} と {{domxref("DOMError")}}</li> +</ul> + +<h3 id="throw_statement" name="throw_statement"><code>throw</code> 文</h3> + +<p><code>throw</code> 文は、例外を投げるために使用します。例外を投げるには、投げたい値を含む式を指定してください。</p> + +<pre class="syntaxbox notranslate">throw <var>expression</var>; +</pre> + +<p>特定の型の式だけではなく、あらゆる式を投げることができます。下記のコードでは、さまざまな型の例外を投げています。</p> + +<pre class="brush: js notranslate">throw 'Error2'; // 文字列型 +throw 42; // 数値型 +throw true; // 論理型 +throw {toString: function() { return "これはオブジェクトです!"; } }; +</pre> + +<div class="note"> +<p><strong>メモ:</strong> 例外を投げる際にオブジェクトを指定することができます。そして、<code>catch</code> ブロックでそのオブジェクトのプロパティを参照することができます。</p> +</div> + +<pre class="brush: js notranslate">// UserException というオブジェクト型を作成 +function UserException(message) { + this.message = message; + this.name = 'UserException'; +} + +// 文字列として使用されるとき(例 : エラーコンソール上)に +// 例外を整形する +UserException.prototype.toString = function() { + return `${this.name}: "${this.message}"`; +} + +// UserException のインスタンスを作成し、それを投げる +throw new UserException('Value too high');</pre> + +<h3 id="try...catch_statement" name="try...catch_statement"><code>try...catch</code> 文</h3> + +<p><code>try...catch</code> 文はテストしたい文のブロックを指定し、さらに投げられる例外に対する 1 つ以上の対処方法を指定します。例外が投げられると、<code>try...catch</code> 文がそれを受け取ります。</p> + +<p><code>try...catch</code> 文は 1 つの <code>try</code> ブロックと 0 個以上の <code>catch</code> ブロックで構成されます。<code>try</code> ブロックは 1 つ以上の文を含み、<code>catch</code> ブロックは <code>try</code> ブロックで例外が投げられた場合の処理を指定する文が含まれます。</p> + +<p>要するに、成功した場合に実行したい <code>try</code> ブロックと、失敗した場合に制御を移行させたい <code>catch</code> ブロックで構成されています。<code>try</code> ブロック内(もしくは <code>try</code> ブロック内から呼び出された関数内)のいずれかの文が例外を投げると、制御は<em>すぐに</em> <code>catch</code> ブロックに移ります。<code>try</code> ブロックで例外が投げられなかった場合、<code>catch</code> ブロックはスキップされます。<code>finally</code> ブロックは <code>try</code> および <code>catch</code> ブロックを実行した後に実行しますが、<code>try...catch</code> 文の後に続く文より先に実行されます。</p> + +<p>次の例では <code>try...catch</code> 文を使用しています。この例では渡された値に基づいて、配列から月の名前を取り出す関数を実行します。値に対応する月の数字 (<code>1</code>–<code>12</code>) が無い場合は <code>"InvalidMonthNo"</code> という値を持つ例外が投げられ、<code>catch</code> ブロックの中の文は <code><var>monthName</var></code> という変数に <code>'unknown'</code> という値をセットします。</p> + +<pre class="brush: js notranslate">function getMonthName(mo) { + mo = mo - 1; // 月の数字を配列のインデックスに合わせる (1 = Jan, 12 = Dec) + let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', + 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + if (months[mo]) { + return months[mo]; + } else { + throw 'InvalidMonthNo'; // throw キーワードが使われている + } +} + +try { // 実行を試みる文 + monthName = getMonthName(myMonth); // この関数が例外を投げる場合がある +} +catch (e) { + monthName = 'unknown'; + logMyErrors(e); // 例外オブジェクトをエラーハンドラーに渡す +} +</pre> + +<h4 id="The_catch_Block" name="The_catch_Block"><code>catch</code> ブロック</h4> + +<p><code>catch</code> ブロックを用いることで、<code>try</code> ブロックで生じうるすべての例外を扱うことができます。</p> + +<pre class="syntaxbox notranslate">catch (<var>catchID</var>) { + <var>statements</var> +} +</pre> + +<p><code>catch</code> ブロックには、<code>throw</code> 文で指定される値を保持しておく識別子 (上記の構文における <code><var>catchID</var></code>) を指定します。投げられた例外についての情報を得るのに、この識別子を使います。</p> + +<p>JavaScript は <code>catch</code> ブロックに入るときにこの識別子を作成します。識別子は <code>catch</code> ブロックの区間だけ存続します。つまり、<code>catch</code> ブロックの実行が終わると、その識別子はもう使えなくなります。</p> + +<p>例えば、次のコードは例外を投げます。例外が生じると、制御が <code>catch</code> ブロックに移ります。</p> + +<pre class="brush: js notranslate">try { + throw 'myException'; // 例外を生成 +} +catch (err) { + // ここには例外を扱う文が入る + logMyErrors(err); // 例外オブジェクトをエラーハンドラに渡す +} +</pre> + +<div class="blockIndicator note"> +<p><strong>ベストプラクティス:</strong> <code>catch</code> ブロック内でコンソールにエラーをログ出力する場合は、<code>console.log()</code> よりも <code>console.error()</code> がデバッグ目的では推奨されています。これはメッセージをエラーとして書式化し、ページによって生成されたエラーメッセージの一覧に追加します。</p> +</div> + +<h4 id="The_finally_block" name="The_finally_block"><code>finally</code> ブロック</h4> + +<p><code>finally</code> ブロックは、<code>try</code> および <code>catch</code> ブロックの実行<em>後</em>に実行される文が入ります。また、<code>finally</code> ブロックの中のコードは <code>try…catch…finally</code> に続く分が実行される<em>前</em>に実行されます。</p> + +<p>また、<code>finally</code> ブロックは例外が発生する<em>かどうかにかかわらず</em>実行されるということに注意することも大切です。また、例外が発生したら、<code>finally</code> ブロック内の文は発生した例外が <code>catch</code> ブロックで処理されなくても実行されます。</p> + +<p><code>finally</code> ブロックを使用することで、例外発生時に適切にスクリプトを停止させることができます。例えば、スクリプトで使用していたリソースを解放しなければならない場合などです。</p> + +<p>次の例ではファイルを開き、そのファイルを使用する文を実行します (サーバー側 JavaScript ではファイルにアクセスできます)。ファイルを開いている間に発生すると、スクリプトが停止する前に <code>finally</code> ブロックでそのファイルを閉じます。ここで <code>finally</code> を使用することで、エラーが発生した場合であってもファイルが開かれたままにならないことを<em>保証</em>します。</p> + +<pre class="brush: js notranslate">openMyFile(); +try { + writeMyFile(theData); // ここでエラーが投げられる可能性がある +} catch(e) { + handleError(e); // エラーを受け取り、それを処理する +} finally { + closeMyFile(); // 常にリソースが閉じられる +} +</pre> + +<p><code>finally</code> ブロックが値を返す場合、その値は <code>try</code> および <code>catch</code> ブロックの <code>return</code> 文にかかわらず <code>try…catch…finally</code> 全体が生成する返値になります。</p> + +<pre class="brush: js notranslate">function f() { + try { + console.log(0); + throw 'bogus'; + } catch(e) { + console.log(1); + return true; // この返値は、finally ブロックが + // 完了するまで保留となる + console.log(2); // ここまで到達しない + } finally { + console.log(3); + return false; // 直前の "return" が上書きされる + console.log(4); // ここまで到達しない + } + // ここで "return false" が実行される + console.log(5); // ここまで到達しない +} +console.log(f()); // 0, 1, 3, false +</pre> + +<p><code>finally</code> ブロックによる返値の上書きは、<code>catch</code> ブロック内で発生した、または再発生した例外にも適用されます。</p> + +<pre class="brush: js notranslate">function f() { + try { + throw 'bogus'; + } catch(e) { + console.log('caught inner "bogus"'); + throw e; // この throw 文は finally ブロックが + // 完了するまで保留になる + } finally { + return false; // 直前の "throw" が上書きされる + } + // ここで "return false" が実行される +} + +try { + console.log(f()); +} catch(e) { + // ここには到達しない + // f() を実行した際、`finally` ブロックが false を返し、 + // 上記の `catch` の中にある `throw` を上書する + console.log('caught outer "bogus"'); +} + +// OUTPUT +// caught inner "bogus" +// false</pre> + +<h4 id="Nesting_try...catch_Statements" name="Nesting_try...catch_Statements">try...catch 文の入れ子</h4> + +<p>1 つ以上の <code>try...catch</code> 文を入れ子にすることができます。</p> + +<p>内側の <code>try...catch</code> 文に <code>catch</code> ブロックが<em>ない</em>場合は次のようになります。</p> + +<ol> + <li><code>finally</code> ブロックを含む必要があります。そして、</li> + <li>囲んでいる <code>try...catch</code> 文の <code>catch</code> ブロックがエラーの照合先としてチェックされます。</li> +</ol> + +<p>詳しくは、<code><a href="/ja/docs/Web/JavaScript/Reference/Statements/try...catch">try...catch</a></code> の中の <a href="/ja/docs/Web/JavaScript/Reference/Statements/try...catch#Nested_try-blocks">nested try-blocks</a> を参照してください。</p> + +<h3 id="Utilizing_Error_objects" name="Utilizing_Error_objects">Error オブジェクトの活用</h3> + +<p>エラーの種類に応じて、<code>name</code> や <code>message</code> プロパティを使ってより詳細なメッセージが得られるようにすることができます。</p> + +<p><code>name</code> は <code>Error</code> のクラス全般 (例えば <code>DOMException</code> や <code>Error</code>) を表し、一方 <code>message</code> は通常、エラーオブジェクトを文字列に変換したものより簡潔なメッセージを表します。</p> + +<p>独自の例外を発生させて、これらのプロパティを有効に活用したい場合 (<code>catch</code> ブロックで独自の例外とシステムの例外とを区別したくない場合など)、<code>Error</code> コンストラクターが使えます。</p> + +<p>例えば、次のようにします。</p> + +<pre class="brush: js notranslate">function doSomethingErrorProne() { + if (ourCodeMakesAMistake()) { + throw (new Error('The message')); + } else { + doSomethingToGetAJavascriptError(); + } +} +⋮ +try { + doSomethingErrorProne(); +} catch (e) { // `console.error()` を実際に使ってログを出力してみます + console.error(e.name); // 'Error' をログ出力 + console.error(e.message); // 'The message'、または JavaScript のエラーメッセージをログ出力 +} + +</pre> + +<p>{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}</p> diff --git a/files/ja/web/javascript/guide/core_language_features/index.html b/files/ja/web/javascript/guide/core_language_features/index.html new file mode 100644 index 0000000000..2161ec589e --- /dev/null +++ b/files/ja/web/javascript/guide/core_language_features/index.html @@ -0,0 +1,10 @@ +--- +title: Core Language Features +slug: Web/JavaScript/Guide/Core_Language_Features +--- +<div> +{{page("/ja/docs/Core_JavaScript_1.5_Guide/Values()")}} +{{page("/ja/docs/Core_JavaScript_1.5_Guide/Variables()")}} +{{page("/ja/docs/Core_JavaScript_1.5_Guide/Constants()")}} +{{page("/ja/docs/Core_JavaScript_1.5_Guide/Literals()")}} +{{page("/ja/docs/Core_JavaScript_1.5_Guide/Unicode()")}}</div> diff --git a/files/ja/web/javascript/guide/creating_a_regular_expression/index.html b/files/ja/web/javascript/guide/creating_a_regular_expression/index.html new file mode 100644 index 0000000000..19935b8b55 --- /dev/null +++ b/files/ja/web/javascript/guide/creating_a_regular_expression/index.html @@ -0,0 +1,31 @@ +--- +title: 正規表現の作成 +slug: Web/JavaScript/Guide/Creating_a_Regular_Expression +--- +<h2 id="正規表現の作成">正規表現の作成</h2> +<p>正規表現は 2 つの方法で作ることができます。</p> +<ul> + <li>次のように、正規表現リテラルを使用する。</li> +</ul> +<pre>var re = /ab+c/; </pre> +<dl> + <dd> + <dl> + <dd> + 正規表現リテラルでは、スクリプトが評価されるときにその正規表現をコンパイルします。正規表現を定数として残しておくときは、この方法を使用するとよりよいパフォーマンスが得られます。</dd> + </dl> + </dd> +</dl> +<ul> + <li>次のように、<a href="/ja/JavaScript/Reference/Global_Objects/RegExp" title="ja/JavaScript/Reference/Global_Objects/RegExp">RegExp</a> オブジェクトのコンストラクタ関数を呼び出す。</li> +</ul> +<pre>var re = new RegExp("ab+c"); </pre> +<dl> + <dd> + <dl> + <dd> + コンストラクタ関数を使用すると、実行時にその正規表現をコンパイルします。正規表現パターンが変わることがわかっている場合や、パターンがわからない場合、ユーザが入力するなど、別のソースからパターンを取得する場合はコンストラクタ関数を使用してください。</dd> + </dl> + </dd> +</dl> +<p>{{ PreviousNext("JavaScript/Guide/Operators/Special_Operators", "JavaScript/Guide/Writing_a_Regular_Expression_Pattern") }}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/defining_getters_and_setters/index.html b/files/ja/web/javascript/guide/creating_new_objects/defining_getters_and_setters/index.html new file mode 100644 index 0000000000..8ee9381575 --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/defining_getters_and_setters/index.html @@ -0,0 +1,89 @@ +--- +title: ゲッターとセッターの定義 +slug: Web/JavaScript/Guide/Creating_New_Objects/Defining_Getters_and_Setters +--- +<h3 id=".E3.82.B2.E3.83.83.E3.82.BF.E3.81.A8.E3.82.BB.E3.83.83.E3.82.BF.E3.81.AE.E5.AE.9A.E7.BE.A9" name=".E3.82.B2.E3.83.83.E3.82.BF.E3.81.A8.E3.82.BB.E3.83.83.E3.82.BF.E3.81.AE.E5.AE.9A.E7.BE.A9">ゲッターとセッターの定義</h3> + +<p>ゲッターはある属性の値を取得するメソッドです。セッターは属性に値を設定するメソッドです。全ての定義済みコアオブジェクトと、新しいプロパティの追加をサポートしているユーザ定義オブジェクトに対してゲッターとセッターを定義できます。ゲッターとセッターの定義にはオブジェクトリテラル構文を使用します。</p> + +<p>以下の例では、ユーザ定義オブジェクト o についてゲッターとセッターがどのように機能するかを説明します。<a href="/ja/docs/SpiderMonkey/Introduction_to_the_JavaScript_shell">JavaScript シェル</a> とは JavaScript コードをバッチモードで、またはインタラクティブにテストすることができる、開発者向けのアプリケーションのことです。</p> + +<p><code>o</code> オブジェクトのプロパティは以下のとおりです。</p> + +<ul> + <li>o.a - 数値</li> + <li>o.b - o.a に 1 を加えて返すゲッター</li> + <li>o.c - o.a の値にその値の 1/2 の値をセットするセッター</li> +</ul> + +<pre>js> o = new Object; +[object Object] +js> o = {a:7, get b() {return this.a+1; }, set c(x) {this.a = x/2}}; +[object Object] +js> o.a +7 +js> o.b +8 +js> o.c = 50 +js> o.a +25 +js> +</pre> + +<p>次の例では、 Date プロトタイプを拡張して定義済み <code>Date</code> クラスの全インスタンスに year プロパティを追加する様子を表しています。<code>Date</code> クラスの既存の <code>getFullYear</code> および <code>setFullYear</code> メソッドを使用して year プロパティのゲッターとセッターを実装します。</p> + +<p>これらの文は year プロパティに対するゲッターとセッターを定義しています。</p> + +<pre>js> var d = Date.prototype; +js> d.__defineGetter__("year", function() { return this.getFullYear(); }); +js> d.__defineSetter__("year", function(y) { this.setFullYear(y); }); +</pre> + +<p>これらの文は <code>Date</code> オブジェクトで定義したゲッターとセッターを使用しています。</p> + +<pre>js> var now = new Date; +js> print(now.year); +2000 +js> now.year=2001; +987617605170 +js> print(now); +Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001 +</pre> + +<div class="note">JavaScript 1.5 の開発期間中に <code>getter =</code> や <code>setter =</code> といった式を使用して新しいゲッターやセッターを既存のオブジェクトで定義するようになっていた時期がありました。この構文は現在は廃止予定であり、現行の JS 1.5 エンジンでは警告を発します。また、将来的には構文エラーになります。使用を避けるようにしてください</div> + +<p> </p> + +<h3 id=".E6.A6.82.E8.A6.81" name=".E6.A6.82.E8.A6.81">概要</h3> + +<p>原則的にゲッターとセッターは次のどちらかに属します。</p> + +<ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers">オブジェクト初期化子</a> を用いて定義されたもの</li> + <li>ゲッターやセッターを追加するメソッドを用いてオブジェクトに後から追加されたもの</li> +</ul> + +<p><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers">オブジェクト初期化子</a> を用いてゲッターやセッターを定義する際には、ゲッターメソッドの先頭に <code>get</code> を、セッターメソッドの先頭に <code>set</code> をそれぞれ付けなくてはなりません。セッターメソッドはセットする新しい値を受けわたすための引数を 1 つだけ持ちます。ゲッターメソッドはパラメータを受け取るようにしてはいけません。</p> + +<pre class="eval">o = { + a:7, + <strong>get</strong> b() { return this.a+1; }, + <strong>set</strong> c(x) { this.a = x/2; } +}; +</pre> + +<p>ゲッターもセッターも、<code>__defineGetter__</code> および <code>__defineSetter__</code> という 2 つの特別なメソッドを用いて、オブジェクト作成後でも、そのオブジェクトに追加することができます。両メソッドの第 1 引数にはそのゲッターやセッターの名前を文字列で指定します。第 2 引数にはゲッターやセッターとして呼び出す関数を指定します。前の例を別の方法で実装したものを以下に示します。</p> + +<pre class="eval">o.__defineGetter__("b", function() { return this.a+1; }); +o.__defineSetter__("c", function(x) { this.a = x/2; }); +</pre> + +<p>2 つの形式のうちどちらを選択するかはあなたのプログラミングスタイルや、目の前の課題次第によります。プロトタイプの定義時にオブジェクト初期化子を使用しているのであれば、最初の形式を選択するのがよいでしょう。この形式はよりコンパクトかつ自然です。ゲッターやセッターを後から追加する必要がある場合は、プロトタイプや特定のオブジェクトを書いていないため、第 2 の形式しか使用できません。第 2 の形式は JavaScript の動的性質をおそらく最もよく表していますが、コードが可読性が下がったり、理解しづらいものとなることがあります。</p> + +<div class="note"> +<p>Firefox 3.0 より前のバージョンではゲッターとセッターが DOM 要素に対してサポートされていません。古いバージョンの Firefox では例外を投げることなく失敗します。そのときに例外が必要であれば、HTMLElement のプロトタイプを変更し <code>(HTMLElement.prototype.__define{{ mediawiki.external('SG') }}etter__)</code>、例外を投げるようにして回避してください。</p> + +<p>Firefox 3.0 では、定義済みのプロパティでゲッターとセッターを定義すると例外が投げられます。そのプロパティは事前に削除しておく必要があります。これは古いバージョンの Firefox には当てはまりません。</p> +</div> + +<p>{{ PreviousNext("JavaScript/Guide/Creating_New_Objects/Using_this_for_Object_References", "JavaScript/Guide/Creating_New_Objects/Deleting_Properties") }}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/defining_methods/index.html b/files/ja/web/javascript/guide/creating_new_objects/defining_methods/index.html new file mode 100644 index 0000000000..74731a99d1 --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/defining_methods/index.html @@ -0,0 +1,39 @@ +--- +title: メソッドの定義 +slug: Web/JavaScript/Guide/Creating_New_Objects/Defining_Methods +--- +<h3 id=".E3.83.A1.E3.82.BD.E3.83.83.E3.83.89.E3.81.AE.E5.AE.9A.E7.BE.A9" name=".E3.83.A1.E3.82.BD.E3.83.83.E3.83.89.E3.81.AE.E5.AE.9A.E7.BE.A9">メソッドの定義</h3> +<p><em>メソッド</em>とはあるオブジェクトに結びつけられた関数のことです。メソッドは、通常の関数の定義と同じ方法で定義します。既存のオブジェクトに関数を結びつけるには次の構文を使用します。</p> +<pre>object.methodname = function_name +</pre> +<p>ここで、<code>object</code> は既存のオブジェクトを、<code>methodname</code> はメソッドに割り当てる名前を、<code>function_name</code> は関数の名前をそれぞれ表しています。</p> +<p>すると、次のようにしてオブジェクトのコンテキストでそのメソッドを呼び出すことができます。</p> +<pre>object.methodname(params); +</pre> +<p>オブジェクトのコンストラクタ関数にメソッドの定義を含めることで、あるオブジェクトの種類についてのメソッドを定義することができます。例えば、以前に定義した car オブジェクトのプロパティを整形して表示する関数を定義します。</p> +<pre>function displayCar() { + var result = "A Beautiful " + this.year + " " + this.make + + " " + this.model; + pretty_print(result); +} +</pre> +<p><code>pretty_print</code> は水平方向の罫線と文字列を表示する関数です。<code>this</code> を使用してそのメソッドを抱えているオブジェクトを参照しています。</p> +<p>次の文</p> +<pre>this.displayCar = displayCar; +</pre> +<p>をオブジェクトの定義に加えることで、この関数を car のメソッドにすることができます。そうすると、<code>car</code> の完全な定義は次のようになります。</p> +<pre>function car(make, model, year, owner) { + this.make = make; + this.model = model; + this.year = year; + this.owner = owner; + this.displayCar = displayCar; +} +</pre> +<p>すると、次のようにして各オブジェクトについて <code>displayCar</code> メソッドを呼び出すことができます。</p> +<pre>car1.displayCar() +car2.displayCar() +</pre> +<p>こうすると次の図のような出力が得られます。</p> +<p><img alt="Image:obja.gif" class="internal" src="/@api/deki/files/1941/=Obja.gif"> <small><strong>図 7.1:メソッドの出力の表示</strong></small></p> +<p>{{ PreviousNext("JavaScript/Guide/Creating_New_Objects/Defining_Properties_for_an_Object_Type", "JavaScript/Guide/Creating_New_Objects/Using_this_for_Object_References") }}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/defining_properties_for_an_object_type/index.html b/files/ja/web/javascript/guide/creating_new_objects/defining_properties_for_an_object_type/index.html new file mode 100644 index 0000000000..b5136b203e --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/defining_properties_for_an_object_type/index.html @@ -0,0 +1,13 @@ +--- +title: Defining Properties for an Object Type +slug: >- + Web/JavaScript/Guide/Creating_New_Objects/Defining_Properties_for_an_Object_Type +--- +<h3 id=".E3.81.82.E3.82.8B.E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AE.E7.A8.AE.E9.A1.9E.E3.81.AB.E5.AF.BE.E3.81.99.E3.82.8B.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E5.AE.9A.E7.BE.A9" name=".E3.81.82.E3.82.8B.E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AE.E7.A8.AE.E9.A1.9E.E3.81.AB.E5.AF.BE.E3.81.99.E3.82.8B.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E5.AE.9A.E7.BE.A9">あるオブジェクトの種類に対するプロパティの定義</h3> +<p><code>prototype</code> プロパティを用いて、定義済みのオブジェクトの種類にプロパティを追加することができます。この方法では、指定した種類のすべてのオブジェクトで共有されるプロパティを定義することになります。そのオブジェクトのあるインスタンス 1 つだけということではありません。次のコードは <code>color</code> プロパティを <code>car</code> という種類の全オブジェクトに追加し、値をオブジェクト <code>car1</code> の <code>color</code> プロパティに代入します。</p> +<pre>car.prototype.color=null; +car1.color="black"; +</pre> +<p>詳しくは <a href="/ja/Core_JavaScript_1.5_Reference" title="ja/Core_JavaScript_1.5_Reference">コア JavaScript リファレンス</a> 内の Function オブジェクトの <a href="/ja/Core_JavaScript_1.5_Reference/Objects/Function#.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3" title="ja/Core_JavaScript_1.5_Reference/Objects/Function#.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3"><code>prototype</code> プロパティ</a> を参照してください。</p> + +<p>{{ PreviousNext("JavaScript/Guide/Creating_New_Objects/Indexing_Object_Properties", "JavaScript/Guide/Creating_New_Objects/Defining_Methods") }}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/deleting_properties/index.html b/files/ja/web/javascript/guide/creating_new_objects/deleting_properties/index.html new file mode 100644 index 0000000000..749ee722f5 --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/deleting_properties/index.html @@ -0,0 +1,20 @@ +--- +title: プロパティの削除 +slug: Web/JavaScript/Guide/Creating_New_Objects/Deleting_Properties +--- +<h2 id="プロパティの削除">プロパティの削除</h2> +<p><code>delete</code> 演算子を用いることでプロパティを除去することができます。次のコードでプロパティの除去方法を示します。</p> +<pre>// 新しいオブジェクト myobj を作成。2 つのプロパティ、a および b を持つ。 +myobj = new Object; +myobj.a = 5; +myobj.b = 12; + +// a プロパティを除去。myobj には b プロパティだけが残っている。 +delete myobj.a; +</pre> +<p><code>delete</code> を使用することでグローバル変数を削除することもできます。ただし、これは <code>var</code> キーワードを使用せずにその変数を宣言した場合のみです。</p> +<pre>g = 17; +delete g; +</pre> +<p>さらなる情報については <a href="/ja/Core_JavaScript_1.5_Guide/Operators/Special_Operators#delete" title="ja/Core_JavaScript_1.5_Guide/Operators/Special_Operators#delete">delete</a> をご覧ください。</p> +<p>{{PreviousNext("JavaScript/Guide/Creating_New_Objects/Defining_Getters_and_Setters", "JavaScript/Guide/Predefined_Core_Objects")}}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/index.html b/files/ja/web/javascript/guide/creating_new_objects/index.html new file mode 100644 index 0000000000..0cbbc1753c --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/index.html @@ -0,0 +1,17 @@ +--- +title: 新しいオブジェクトの作成 +slug: Web/JavaScript/Guide/Creating_New_Objects +--- +<h3 id=".E6.96.B0.E3.81.97.E3.81.84.E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AE.E4.BD.9C.E6.88.90" name=".E6.96.B0.E3.81.97.E3.81.84.E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AE.E4.BD.9C.E6.88.90">新しいオブジェクトの作成</h3> +<p>JavaScript には多くの定義済みオブジェクトがあります。さらに、自分でオブジェクトを作り出すことができます。JavaScript 1.2 以降では、オブジェクト初期化子を用いてオブジェクトを作成できます。もう 1 つの方法として、まずコンストラクタ関数を作成し、それからその関数と new 演算子を用いてオブジェクトのインスタンスを作成することもできます。</p> +<ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers">オブジェクト初期化子の使用</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_a_Constructor_Function" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_a_Constructor_Function">コンストラクタ関数の使用</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Indexing_Object_Properties" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Indexing_Object_Properties">オブジェクトのプロパティのインデックス付け</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Properties_for_an_Object_Type" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Properties_for_an_Object_Type">あるオブジェクトの種類に対するプロパティの定義</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Methods" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Methods">メソッドの定義</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_this_for_Object_References" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_this_for_Object_References">this を用いたオブジェクト参照</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters">ゲッタとセッタの定義</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Deleting_Properties" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Deleting_Properties">プロパティの削除</a></li> +</ul> +<p>{{ PreviousNext("JavaScript/Guide/Objects_and_Properties", "JavaScript/Guide/Creating_New_Objects/Using_Object_Initializers") }}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/indexing_object_properties/index.html b/files/ja/web/javascript/guide/creating_new_objects/indexing_object_properties/index.html new file mode 100644 index 0000000000..024de85654 --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/indexing_object_properties/index.html @@ -0,0 +1,9 @@ +--- +title: オブジェクトのプロパティに対するインデックス付け +slug: Web/JavaScript/Guide/Creating_New_Objects/Indexing_Object_Properties +--- +<h3 id=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AE.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E3.82.A4.E3.83.B3.E3.83.87.E3.83.83.E3.82.AF.E3.82.B9.E4.BB.98.E3.81.91" name=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AE.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E3.82.A4.E3.83.B3.E3.83.87.E3.83.83.E3.82.AF.E3.82.B9.E4.BB.98.E3.81.91">オブジェクトのプロパティのインデックス付け</h3> +<p>JavaScript 1.0 では、オブジェクトのプロパティを、そのプロパティ名や順序のインデックスで参照できます。しかしながら、JavaScript 1.1 以降では、最初にプロパティをその名前で定義すると、常にその名前で参照しなければならず、また、最初にプロパティをインデックスで定義すると、常にそのインデックスで参照しなければなりません。</p> +<p>先の Car というオブジェクトの種類の例のようにコンストラクタ関数を用いてオブジェクトとそのプロパティを作成したとき、また、それぞれのプロパティを明示的に定義したとき(例:<code>myCar.color = "red"</code>)に、これは適用されます。そのため、<code>myCar{{ mediawiki.external(5) }} = "25 mpg"</code> のように、最初にインデックスを用いてオブジェクトのプロパティを定義した場合、<code>myCar{{ mediawiki.external(5) }}</code> のようにそのプロパティを後から参照できるようになります。</p> +<p>このルールの例外は、<code>forms</code> 配列のように HTML から反映されたオブジェクトです。これらの配列内のオブジェクトは、その順番を表す数(文書内のどこにあるかに基づく)か、またはその名前(定義されている場合)のどちらかで常に参照できます。例えば、文書内の 2 番目の <code><FORM></code> タグが "myForm" という <code>NAME</code> 属性を持っている場合、<code>document.forms{{ mediawiki.external(1) }}</code> や <code>document.forms{{ mediawiki.external('\"myForm\"') }}</code> や <code>document.myForm</code> とすることでそのフォームを参照できます。</p> +<p>{{ PreviousNext("JavaScript/Guide/Creating_New_Objects/Using_a_Constructor_Function", "JavaScript/Guide/Creating_New_Objects/Defining_Properties_for_an_Object_Type") }}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/using_a_constructor_function/index.html b/files/ja/web/javascript/guide/creating_new_objects/using_a_constructor_function/index.html new file mode 100644 index 0000000000..f3abc30e89 --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/using_a_constructor_function/index.html @@ -0,0 +1,57 @@ +--- +title: コンストラクタ関数の使用 +slug: Web/JavaScript/Guide/Creating_New_Objects/Using_a_Constructor_Function +--- +<h3 id=".E3.82.B3.E3.83.B3.E3.82.B9.E3.83.88.E3.83.A9.E3.82.AF.E3.82.BF.E9.96.A2.E6.95.B0.E3.81.AE.E4.BD.BF.E7.94.A8" name=".E3.82.B3.E3.83.B3.E3.82.B9.E3.83.88.E3.83.A9.E3.82.AF.E3.82.BF.E9.96.A2.E6.95.B0.E3.81.AE.E4.BD.BF.E7.94.A8">コンストラクタ関数の使用</h3> +<p>もう 1 つの方法として、次の 2 つのステップでオブジェクトを作成することができます。</p> +<ol> + <li>コンストラクタ関数を書くことでオブジェクトの種類を定義する。</li> + <li>new を用いてそのオブジェクトのインスタンスを作成する。</li> +</ol> +<p>オブジェクトの種類を定義するために、その名前、プロパティ、メソッドを定義する関数を作成する必要があります。例えば、車についてのオブジェクトの種類を作成したいとします。そしてこの種類のオブジェクトに <code>car</code> という名前を付け、make、model、および year というプロパティを持たせたいとします。こうするためには次のような関数を書きます。</p> +<pre>function car(make, model, year) { + this.make = make; + this.model = model; + this.year = year; +} +</pre> +<p>関数に渡された値に基づいてオブジェクトのプロパティに値を代入するために <code>this</code> を使用しています。</p> +<p>すると、次のようにして <code>mycar</code> というオブジェクトを作成することができるようになります。</p> +<pre>mycar = new car("Eagle", "Talon TSi", 1993); +</pre> +<p>この文は <code>mycar</code> を作成し、そのプロパティ用に指定した値を代入します。その結果、<code>mycar.make</code> の値は "Eagle" という文字列、<code>mycar.year</code> は 1993 という整数というようになります。</p> +<p><code>new</code> を呼び出すことで <code>car</code> オブジェクトをいくらでも作ることができます。</p> +<pre>kenscar = new car("Nissan", "300ZX", 1992); +vpgscar = new car("Mazda", "Miata", 1990); +</pre> +<p>それ自身別のオブジェクトであるというようなプロパティを持つオブジェクトを作ることができます。例えば、次のように <code>person</code> というオブジェクトを定義するとします。</p> +<pre>function person(name, age, sex) { + this.name = name; + this.age = age; + this.sex = sex; +} +</pre> +<p>そして、次のように 2 つの新しい person オブジェクトのインスタンスを作成します。</p> +<pre>rand = new person("Rand McKinnon", 33, "M"); +ken = new person("Ken Jones", 39, "M"); +</pre> +<p>次のようにして、car の定義を書き換えて、<code>person</code> オブジェクトをとる owner プロパティを持たせることができます。</p> +<pre>function car(make, model, year, owner) { + this.make = make; + this.model = model; + this.year = year; + this.owner = owner; +} +</pre> +<p>新しいオブジェクトのインスタンスを作成するために、次のようにします。</p> +<pre>car1 = new car("Eagle", "Talon TSi", 1993, rand); +car2 = new car("Nissan", "300ZX", 1992, ken); +</pre> +<p>新しいオブジェクトの作成時に文字列リテラルや整数値を渡す代わりに、上記の文ではオブジェクト <code>rand</code> および <code>ken</code> を所有者を表す引数として渡しています。car2 の所有者の名前を知りたい場合は次のプロパティにアクセスすることで可能になります。</p> +<pre>car2.owner.name +</pre> +<p>以前に定義したオブジェクトにいつでもプロパティを追加できることに注意してください。例えば次の文</p> +<pre>car1.color = "black" +</pre> +<p>はプロパティ <code>color</code> を car1 に追加し、それに "black" という値を代入します。しかしながら、この方法では他のどのオブジェクトにも影響を与えません。同じ種類の全オブジェクトに新しいプロパティを追加するには、そのプロパティを car というオブジェクトの種類の定義に追加する必要があります。</p> +<p>{{ PreviousNext("JavaScript/Guide/Creating_New_Objects/Using_Object_Initializers", "JavaScript/Guide/Creating_New_Objects/Indexing_Object_Properties") }}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/using_object_initializers/index.html b/files/ja/web/javascript/guide/creating_new_objects/using_object_initializers/index.html new file mode 100644 index 0000000000..0a817b5407 --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/using_object_initializers/index.html @@ -0,0 +1,23 @@ +--- +title: オブジェクト初期化子の使用 +slug: Web/JavaScript/Guide/Creating_New_Objects/Using_Object_Initializers +--- +<h3 id=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E5.88.9D.E6.9C.9F.E5.8C.96.E5.AD.90.E3.81.AE.E4.BD.BF.E7.94.A8" name=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E5.88.9D.E6.9C.9F.E5.8C.96.E5.AD.90.E3.81.AE.E4.BD.BF.E7.94.A8">オブジェクト初期化子の使用</h3> +<p>コンストラクタ関数を使用してオブジェクトを作成する方法だけではなく、オブジェクト初期化子を使用してもオブジェクトを作成することができます。オブジェクト初期化子を使うことはリテラル表示を用いてオブジェクトを作成するということです。「オブジェクト初期化子」は C++ でも同じ意味で使用されている用語です。</p> +<p>オブジェクト初期化子を使用したオブジェクトの構文は次のとおりです。</p> +<pre class="eval">var obj = { property_1: value_1, // property_# は識別子でもよい + 2: value_2, // あるいは数値でもよい + ..., + "property_n": value_n }; // あるいは文字列でもよい +</pre> +<p>ここで、<code>obj</code> は新しいオブジェクトの名前を、各 <code>property_<em>i</em></code> は識別子(名前、数値、文字列リテラルのいずれか)を、各 <code>value_<em>i</em></code> はその値を <code>property_<em>i</em></code> に代入する式をそれぞれ表しています。<code>obj</code> および代入部分はなくてもかまいません。このオブジェクトを別の場所で参照する必要がないのであれば変数に代入する必要はありません。(文が期待されているところにオブジェクトリテラルを置く場合、リテラルを丸括弧で囲み、ブロック文と間違われないようにする必要があるかもしれません。)</p> +<p>トップレベルのスクリプトでオブジェクト初期化子を使用してオブジェクトを作成した場合、JavaScript はオブジェクトリテラルを含む式を評価するたびにそのオブジェクトを解釈します。さらに、関数内で使用された初期化子はその関数が呼び出されるたびに作成されます。</p> +<p>次の文は、式 cond が true の場合かつその場合に限り、あるオブジェクトを作成し、それを変数 <code>x</code> に代入します。</p> +<pre class="eval">if (cond) x = {hi:"there"}; +</pre> +<p>次の例は 3 つのプロパティを持つ <code>myHonda</code> を作成します。<code>engine</code> プロパティは自らもプロパティを持つオブジェクトでもあることに注意してください。</p> +<pre class="eval">myHonda = {color:"red",wheels:4,engine:{cylinders:4,size:2.2}}; +</pre> +<p>オブジェクト初期化子を使用して配列を作成することもできます。<a href="/ja/Core_JavaScript_1.5_Guide/Literals#.E9.85.8D.E5.88.97.E3.83.AA.E3.83.86.E3.83.A9.E3.83.AB" title="ja/Core_JavaScript_1.5_Guide/Literals#.E9.85.8D.E5.88.97.E3.83.AA.E3.83.86.E3.83.A9.E3.83.AB">配列リテラル</a> を参照してください。</p> +<p>JavaScript 1.1 以前ではオブジェクト初期化子を使用することはできません。コンストラクタ関数を使用するか、他のオブジェクトが備えているそのような用途の関数を使用しないとオブジェクトを作成できません。<a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_a_Constructor_Function" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_a_Constructor_Function">コンストラクタ関数の使用</a> をご覧ください。</p> +<p>{{ PreviousNext("JavaScript/Guide/Creating_New_Objects", "JavaScript/Guide/Creating_New_Objects/Using_a_Constructor_Function") }}</p> diff --git a/files/ja/web/javascript/guide/creating_new_objects/using_this_for_object_references/index.html b/files/ja/web/javascript/guide/creating_new_objects/using_this_for_object_references/index.html new file mode 100644 index 0000000000..5fbd3b8aff --- /dev/null +++ b/files/ja/web/javascript/guide/creating_new_objects/using_this_for_object_references/index.html @@ -0,0 +1,25 @@ +--- +title: this を用いたオブジェクト参照 +slug: Web/JavaScript/Guide/Creating_New_Objects/Using_this_for_Object_References +--- +<h3 id="this_.E3.82.92.E7.94.A8.E3.81.84.E3.81.9F.E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E5.8F.82.E7.85.A7" name="this_.E3.82.92.E7.94.A8.E3.81.84.E3.81.9F.E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E5.8F.82.E7.85.A7">this を用いたオブジェクト参照</h3> +<p>JavaScript にはカレントオブジェクトを参照するメソッド内で使用できる特殊なキーワード、this があります。例えば、あるオブジェクトの value プロパティの妥当性を確認する <code>validate</code> という関数があるとします。関数にはそのオブジェクトと、上限および下限の値を渡します。</p> +<pre>function validate(obj, lowval, hival) { + if ((obj.value < lowval) || (obj.value > hival)) + alert("Invalid Value!"); +} +</pre> +<p>各フォーム要素の <code>onchange</code> イベントハンドラにおいて <code>validate</code> を呼び出します。this を使うことで <code>form</code> 要素を渡すことができます。次の例をご覧ください。</p> +<pre><input type="text" name="age" size="3" + onChange="validate(this, 18, 99)"> +</pre> +<p>一般に <code>this</code> はあるメソッド内でそのメソッドを呼び出したオブジェクトを参照します。</p> +<p><code>form</code> プロパティと組み合わせることで、<code>this</code> はカレントオブジェクトの親のフォームを参照できます。次の例では、<code>myForm</code> というフォームに <code>Text</code> オブジェクトとボタンが格納されています。ユーザがボタンをクリックすると、<code>Text</code> オブジェクトの値にフォーム名がセットされます。ボタンの <code>onclick</code> イベントハンドラは <code>this.form</code> を利用して親のフォームである <code>myForm</code> を参照します。</p> +<pre><form name="myForm"> +<p><label>Form name:<input type="text" name="text1" value="Beluga"></label> +<p><input name="button1" type="button" value="Show Form Name" + onclick="this.form.text1.value=this.form.name"> +</p> +</form> +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Creating_New_Objects/Defining_Methods", "JavaScript/Guide/Creating_New_Objects/Defining_Getters_and_Setters") }}</p> diff --git a/files/ja/web/javascript/guide/details_of_the_object_model/index.html b/files/ja/web/javascript/guide/details_of_the_object_model/index.html new file mode 100644 index 0000000000..80ea36d1ca --- /dev/null +++ b/files/ja/web/javascript/guide/details_of_the_object_model/index.html @@ -0,0 +1,728 @@ +--- +title: オブジェクトモデルの詳細 +slug: Web/JavaScript/Guide/Details_of_the_Object_Model +tags: + - Guide + - Intermediate + - JavaScript + - Object + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}</div> + +<p class="summary">JavaScript は、クラスではなく、プロトタイプに基づいたオブジェクトベースの言語です。この基本的な違いにより、JavaScript がオブジェクト階層構造をどのように作り上げているか、またプロパティやその値の継承方法が表面上分かりにくいものとなっています。本章ではこれらの実態を明らかにしていきます。</p> + +<p>本章では、読者が JavaScript をある程度理解している、および単純なオブジェクトを作成するために JavaScript の関数を使用したことがあると想定しています。</p> + +<h2 id="Class-based_vs._prototype-based_languages" name="Class-based_vs._prototype-based_languages">クラスベース言語とプロトタイプベース言語</h2> + +<p>Java や C++ といったクラスベースのオブジェクト指向言語は、クラスとインスタンスという 2種類の異なる実体があるという概念に基づいています。</p> + +<ul> + <li><em>クラス</em>は、あるオブジェクトの集まりを特徴付けるすべてのプロパティ(Java ではメソッドとフィールドを、C++ ではメンバーをプロパティとみなします)を定義します。クラスとは、自身を表すオブジェクト集合のメンバーよりも、より抽象的です。例えば、<code>Employee</code> クラスは従業員すべての集合を表現することができます。</li> + <li>一方、<em>インスタンス</em>はクラスを具体化したものです。つまり、クラスのメンバーの 1 つです。例えば、<code>Victoria</code> は <code>Employee</code> クラスのインスタンスになることができます。このインスタンスは、特定の個人を従業員として表すものです。インスタンスは、その親クラスのプロパティを(過不足なく)正確に保持します。</li> +</ul> + +<p>JavaScript のようなプロトタイプベースの言語は、この区別がありません。単にオブジェクトがあるだけです。プロトタイプベース言語には、<em>{{原語併記("プロトタイプオブジェクト", "prototypical object")}}</em> という概念があります。このオブジェクトは、新しいオブジェクトの初期プロパティの取得元になるテンプレートとして使用されます。どのオブジェクトも独自のプロパティを指定できます。これはオブジェクト作成時にも実行時にも可能です。さらに、どのオブジェクトも別のオブジェクトに対する<em>プロトタイプ</em>として関連づけることができます。2 つ目のオブジェクトに対し 1 つ目のオブジェクトのプロパティを共有させることもできます。</p> + +<h3 id="Defining_a_class" name="Defining_a_class">クラスの定義</h3> + +<p>クラスベース言語では、独立した<em>クラス定義</em>でクラスを定義します。定義では<em>コンストラクター</em>と呼ばれる特殊なメソッドを使用して、そのクラスのインスタンスを作成することができます。コンストラクターメソッドは、インスタンスのプロパティに対する初期値を指定することができます。また、作成時に他の適切な処理を実行することもできます。<code>new</code> 演算子をコンストラクターメソッドと一緒に用いることで、クラスのインスタンスを作成できます。</p> + +<p>JavaScript は同様のモデルに従っていますが、コンストラクターとは別のクラス定義はありません。その代わりに、プロパティと値からなる特別な初期セットを持つオブジェクトを作成する、コンストラクター関数を定義します。どの JavaScript 関数もコンストラクターとして使用できます。<code>new</code> 演算子をコンストラクター関数とともに使用することで、新しいオブジェクトを作成します。</p> + +<div class="blockIndicator note"> +<p>ECMAScript 2015 で導入された<a href="/ja/docs/Web/JavaScript/Reference/Classes">クラス宣言</a>について。</p> + +<blockquote> +<p>ECMAScript 2015 で導入された JavaScript のクラスは、主に JavaScript の既存のプロトタイプベースの継承に対する糖衣構文です。クラス構文は、JavaScript に新しいオブジェクト指向の継承モデルを導入するものでは<em>ありません</em>。</p> +</blockquote> +</div> + +<h3 id="Subclasses_and_inheritance" name="Subclasses_and_inheritance">サブクラスと継承</h3> + +<p>クラスベース言語では、クラス定義を通してクラスの階層を作ります。クラス定義では、新しいクラスが既存のクラスの<em>サブクラス</em>になるよう指定することができます。サブクラスはスーパークラスの全プロパティを継承します。さらに、新たなプロパティの追加や継承したプロパティの変更もできます。例えば、<code>Employee</code> クラスが <code>name</code> および <code>dept</code> プロパティのみを含み、<code>Manager</code> は <code>reports</code> プロパティが追加された <code>Employee</code> のサブクラスであるとします。この場合、<code>Manager</code> クラスのインスタンスは <code>name</code>、<code>dept</code>、<code>reports</code> の 3 つのプロパティをすべて持つことになります。</p> + +<p>JavaScript では、プロトタイプオブジェクトを何らかのコンストラクター関数に結びつけられるようにすることで、継承を実装しています。そのため、全く同じように <code>Employee</code> と <code>Manager</code> の例を作成できますが、使用する用語が若干異なります。まず、<code>Employee</code> コンストラクター関数を定義し、<code>name</code> および <code>dept</code> プロパティを定義します。次に <code>Manager</code> コンストラクター関数を定義し、<code>Employee</code> コンストラクター関数を呼び出して <code>reports</code> プロパティを定義します。最後に、<code>Manager</code> コンストラクト関数の <code>prototype</code> に <code>Employee.prototype</code> から派生した新しいオブジェクトを代入します。そして新しい <code>Manager</code> を作成すると、このオブジェクトは <code>Employee</code> オブジェクトから <code>name</code> および <code>dept</code> プロパティを継承します。</p> + +<h3 id="Adding_and_removing_properties" name="Adding_and_removing_properties">プロパティの追加と削除</h3> + +<p>クラスベース言語では一般的にクラスをコンパイル時に生成し、コンパイル時または実行時にクラスのインスタンスを作成します。クラス定義後に、そのクラスのプロパティの数や型を変更することはできません。しかし JavaScript では、どのオブジェクトでも実行時にプロパティの追加や削除ができます。ある一連のオブジェクトでプロトタイプとして使用されているオブジェクトにプロパティを追加すると、それをプロトタイプとするオブジェクトにも新しいプロパティが追加されます。</p> + +<h3 id="Summary_of_differences" name="Summary_of_differences">相違点の概要</h3> + +<p>こうした相違点の要約を以下の表にまとめています。本章では後ほど、JavaScript のコンストラクターとプロトタイプを用いたオブジェクト階層作成の詳細を説明し、Java における手法との比較も行っていきます。</p> + +<table class="standard-table"> + <caption>クラスベース (Java) とプロトタイプベース (JavaScript) のオブジェクトシステムの比較</caption> + <thead> + <tr> + <th scope="col">クラスベース (Java)</th> + <th scope="col">プロトタイプベース (JavaScript)</th> + </tr> + </thead> + <tbody> + <tr> + <td>クラスとインスタンスは異なる実体です。</td> + <td>すべてのオブジェクトは別のオブジェクトを継承できます。</td> + </tr> + <tr> + <td>クラス定義を用いてクラスを定義します。また、コンストラクターメソッドを用いてクラスをインスタンス化します。</td> + <td>コンストラクター関数を用いて一連のオブジェクトを定義および作成します。</td> + </tr> + <tr> + <td><code>new</code> 演算子を用いて単一のオブジェクトを生成します。</td> + <td>同様です。</td> + </tr> + <tr> + <td>既存のクラスのサブクラスを定義するクラス定義を用いて、オブジェクト階層を構築します。</td> + <td>コンストラクター関数に結びつけられたプロトタイプとしてオブジェクトを代入することで、オブジェクト階層を構築します。</td> + </tr> + <tr> + <td>クラスチェーンに従ってプロパティを継承します。</td> + <td>プロトタイプチェーンに従ってプロパティを継承します。</td> + </tr> + <tr> + <td>クラス定義が、クラスから作られた全インスタンス<em>すべての</em>プロパティを定義します。実行時に動的にプロパティを追加することはできません。</td> + <td>コンストラクター関数またはプロトタイプによって、<em>一連の初期化された</em>プロパティが指定されます。個々のオブジェクトやオブジェクトのセット全体へ動的にプロパティを追加したり、それらからプロパティを削除したりできます。</td> + </tr> + </tbody> +</table> + +<h2 id="The_employee_example" name="The_employee_example">事例 : 従業員モデル</h2> + +<p>ここからは、次の図で示す従業員の階層を使用していきます。</p> + +<div style="display: table-row;"> +<div style="display: table-cell; width: 350px; text-align: center; vertical-align: middle; padding: 10px;"> +<p>例で使用するオブジェクトの簡単な階層図 :</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/3060/figure8.1.png"></p> +</div> + +<div style="display: table-cell; vertical-align: middle; padding: 10px;"> +<ul> + <li><code>Employee</code> には、プロパティ <code>name</code>(デフォルト値は空文字列)および <code>dept</code>(既定値は "general")があります。</li> + <li><code>Manager</code> は <code>Employee</code> をベースとしています。<code>reports</code> プロパティ(デフォルト値は空の配列、値として <code>Employee</code> オブジェクトの配列を保持する)が追加されています。</li> + <li><code>WorkerBee</code> も <code>Employee</code> をベースとしています。<code>projects</code> プロパティ(デフォルト値は空の配列、値として文字列の配列を保持する)が追加されています。</li> + <li><code>SalesPerson</code> は <code>WorkerBee</code> をベースとしています。<code>quota</code> プロパティ(デフォルトの値は 100)が追加され、さらに <code>dept</code> プロパティを "sales" という値で上書きします。これは、販売員が全員同じ部署に所属していることを示します。</li> + <li><code>Engineer</code> は <code>WorkerBee</code> をベースとしています。<code>machine</code> プロパティ(デフォルトの値は空文字列)が追加され、さらに <code>dept</code> プロパティを "engineering" という値で上書きします。</li> +</ul> +</div> +</div> + +<h2 id="Creating_the_hierarchy" name="Creating_the_hierarchy">階層の作成</h2> + +<p>Employee の階層を実装するための、適切なコンストラクター関数を定義する方法はいくつかあります。どの方法で定義するかは、アプリケーションで何を実現したいかに大きく依存します。</p> + +<p>この章では、継承がどのように機能するかを表現するため、とても単純な(かつ比較的柔軟でない)定義の使い方でこれを説明していきます。この定義方法では、オブジェクト作成時にプロパティの値を指定することはできません。新しく作成されるオブジェクトには単に既定値が割り当てられるだけで、値は後から変更できます。</p> + +<p>実際のアプリケーションでは、オブジェクト作成時にプロパティの値を指定できるコンストラクターを定義することになるでしょう(詳しくは<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#More_flexible_constructors">より柔軟なコンストラクター</a>をご覧ください)。今回はこれらの単純な定義を使用して、継承はどのようにして起こるのかを実際に示していくことにします。</p> + +<p>以下に示すように、Java と JavaScript の <code>Employee</code> の定義は似ています。両者の相違点は、Java では各プロパティに型を指定する必要があるのに対して、JavaScript ではその必要がないことです(これは JavaScript が弱い型付けの言語であるのに対して Java が <a href="https://ja.wikipedia.org/wiki/%E5%9E%8B%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0#.E5.BC.B7.E3.81.84.E5.9E.8B.E4.BB.98.E3.81.91.E3.81.A8.E5.BC.B1.E3.81.84.E5.9E.8B.E4.BB.98.E3.81.91">強い型付け言語</a>だからです)。</p> + +<h4 id="JavaScript_using_this_may_cause_an_error_for_the_following_examples" name="JavaScript_using_this_may_cause_an_error_for_the_following_examples">JavaScript (これを使用すると、以下の例でエラーが発生する可能性があります)</h4> + +<pre class="brush: js notranslate">class Employee { + constructor() { + this.name = ''; + this.dept = 'general'; + } +} + +</pre> + +<h4 id="JavaScript_**_かわりにこれを使う">JavaScript ** (かわりにこれを使う)</h4> + +<pre class="brush: js notranslate">function Employee() { + this.name = ''; + this.dept = 'general'; +} + +</pre> + +<h4 id="Java" name="Java">Java</h4> + +<pre class="brush: java notranslate">public class Employee { + public String name = ""; + public String dept = "general"; +} +</pre> + +<p><code>Manager</code> および <code>WorkerBee</code> の定義では、継承チェーンにおいて隣接する上位オブジェクトの指定方法に違いがあります。JavaScript では、プロトタイプインスタンスをコンストラクター関数の <code>prototype</code> プロパティの値として追加し、さらに <code>prototype.constructor</code> をコンストラクター関数で上書きします。コンストラクターを定義した後なら、いつでもこれを行うことができます。Java では、クラス定義内でスーパークラスを指定します。クラス定義の外部でスーパークラスを変更することはできません。</p> + +<h4 id="JavaScript" name="JavaScript">JavaScript</h4> + +<pre class="brush: js notranslate">function Manager() { + Employee.call(this); + this.reports = []; +} +Manager.prototype = Object.create(Employee.prototype); +Manager.prototype.constructor = Manager; + +function WorkerBee() { + Employee.call(this); + this.projects = []; +} +WorkerBee.prototype = Object.create(Employee.prototype); +WorkerBee.prototype.constructor = WorkerBee; +</pre> + +<h4 id="Java_2" name="Java_2">Java</h4> + +<pre class="brush: java notranslate">public class Manager extends Employee { + public Employee[] reports = + new Employee[0]; +} + + + +public class WorkerBee extends Employee { + public String[] projects = new String[0]; +} + + +</pre> + +<p><code>Engineer</code> および <code>SalesPerson</code> の定義は、<code>WorkerBee</code> の子孫、したがって <code>Employee</code> の子孫でもあるオブジェクトを作成します。こうした種類のオブジェクトは、チェーンの上位にある全オブジェクトのプロパティを持ちます。さらに、これらの定義によって、継承された <code>dept</code> のプロパティ値を、自身のオブジェクト固有の新しい値に上書きしています。</p> + +<h4 id="JavaScript_2" name="JavaScript_2">JavaScript</h4> + +<pre class="brush: js notranslate">function SalesPerson() { + WorkerBee.call(this); + this.dept = 'sales'; + this.quota = 100; +} +SalesPerson.prototype = Object.create(WorkerBee.prototype); +SalesPerson.prototype.constructor = SalesPerson; + +function Engineer() { + WorkerBee.call(this); + this.dept = 'engineering'; + this.machine = ''; +} +Engineer.prototype = Object.create(WorkerBee.prototype) +Engineer.prototype.constructor = Engineer; +</pre> + +<h4 id="Java_3" name="Java_3">Java</h4> + +<pre class="brush: java notranslate">public class SalesPerson extends WorkerBee { + public String dept = "sales"; + public double quota = 100.0; +} + + +public class Engineer extends WorkerBee { + public String dept = "engineering"; + public String machine = ""; +} + +</pre> + +<p>これらの定義を使用して、プロパティがデフォルト値をとる、オブジェクトのインスタンスを作成することができます。下記の図は、これらの JavaScript の定義を使用して新しいオブジェクトを作成する方法を示しています。また、新しいオブジェクトのプロパティの値も示しています。</p> + +<div class="note"> +<p><strong>注:</strong> <em>インスタンス</em>という用語は、クラスベースの言語においては特定の技術的な意味を持っています。これらの言語では、インスタンスとはクラスの個々のメンバであり、クラスとは根本的に異なるものです。JavaScript では、「インスタンス」にこのような技術的な意味はありません。なぜならば、JavaScript ではクラスとインスタンスとの間にそのような違いがないためです。しかしながら、JavaScript について話す際に「インスタンス」を、個々のコンストラクター関数を用いて作成されたオブジェクトを意味する言葉として、非公式に使用することがあります。例えば <code>jane</code> は非公式に <code>Engineer</code> のインスタンスであると言うこともできます。同様に、「親」、「子」、「祖先」、「子孫」という用語は JavaScript において公式な意味を持ちませんが、プロトタイプチェーンにおいて上や下にあるオブジェクトについて言及する際に、それらを非公式に使用してもかまいません。</p> +</div> + +<h3 id="Creating_objects_with_simple_definitions" name="Creating_objects_with_simple_definitions">簡単な定義によるオブジェクトの作成</h3> + +<div class="twocolumns"> +<h4 id="Object_hierarchy" name="Object_hierarchy">オブジェクト階層</h4> + +<p>下記のような階層が、右に書かれたコードを使って作成されます。</p> + +<p><img src="https://mdn.mozillademos.org/files/10412/=figure8.3.png"></p> +<br> +<br> +<br> +<br> +<br> +<br> +<br> +<br> +<br> +<br> +<br> + +<h4 id="individual_objects" name="individual_objects">個別のオブジェクト = Jim, Sally, Mark, Fred, Jane, など。<br> + コンストラクターから生成された「インスタンス」</h4> + +<pre class="brush: js notranslate">var jim = new Employee; +// Parentheses can be omitted if the +// constructor takes no arguments. +// jim.name is '' +// jim.dept is 'general' + +var sally = new Manager; +// sally.name is '' +// sally.dept is 'general' +// sally.reports is [] + +var mark = new WorkerBee; +// mark.name is '' +// mark.dept is 'general' +// mark.projects is [] + +var fred = new SalesPerson; +// fred.name is '' +// fred.dept is 'sales' +// fred.projects is [] +// fred.quota is 100 + +var jane = new Engineer; +// jane.name is '' +// jane.dept is 'engineering' +// jane.projects is [] +// jane.machine is '' +</pre> +</div> + +<h2 id="Object_properties" name="Object_properties">オブジェクトのプロパティ</h2> + +<p>この章では、オブジェクトがどのようにしてプロトタイプチェーンにより他のオブジェクトからプロパティを継承するのか、また実行時にプロパティを追加すると何が起きるのかについて考察します。</p> + +<h3 id="Inheriting_properties" name="Inheriting_properties">プロパティの継承</h3> + +<p>次の文を用いて、<code>mark</code> オブジェクトを <code>WorkerBee</code> として生成するとしましょう。</p> + +<pre class="brush: js notranslate">var mark = new WorkerBee; +</pre> + +<p>JavaScript は <code>new</code> 演算子に出会うと、新しく汎用オブジェクトを作成し、暗黙に内部プロパティ [[Prototype]] の値を <code>WorkerBee.prototype</code> の値に設定し、その新しいオブジェクトを <code>this</code> キーワードの値として <code>WorkerBee</code> コンストラクター関数に渡します。内部の [[Prototype]] プロパティはプロパティ値を返すために使用されるプロトタイプチェーンを決定します。これらのプロパティが設定されると JavaScript は新しいオブジェクトを返し、代入文によって変数 <code>mark</code> にそのオブジェクトが設定されます。</p> + +<p>このプロセスでは、<code>mark</code> がプロトタイプチェーンによって継承するプロパティは、<code>mark</code> オブジェクトの値には(<em>ローカル</em>値としては)明示的に格納されません。プロパティの値を使用するときは、JavaScript はまずその値がオブジェクトに存在しているかを確認します。存在する場合は、その値が返されます。値がローカルには存在しない場合、JavaScript はプロトタイプチェーンを確認します(内部的な [[Prototype]] プロパティを使用)。プロトタイプチェーン内のオブジェクトがそのプロパティの値を持っている場合は、その値が返されます。そのようなプロパティが見つからない場合、JavaScript はオブジェクトにそのプロパティがないと報告します。このようにして、<code>mark</code> オブジェクトは次のようなプロパティと値を持つことになります。</p> + +<pre class="brush: js notranslate">mark.name = ''; +mark.dept = 'general'; +mark.projects = []; +</pre> + +<p><code>mark</code> オブジェクトは、Employee コンストラクターによって <code>name</code> および <code>dept</code> プロパティのローカル値が割り当てられます。<code>projects</code> プロパティには、<code>WorkerBee</code> コンストラクターによってローカル値が代入されます。JavaScript ではこのようにプロパティとその値の継承を行います。このプロセスの詳細は<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Property_inheritance_revisited">プロパティの継承、再び</a>にて説明します。</p> + +<p>これらのコンストラクターはインスタンス固有の値を渡せないため、この情報は汎用的になります。プロパティの値は、<code>WorkerBee</code> によって作成されるすべての新しいオブジェクトに共通の既定値になります。もちろん、これらのどのプロパティでも値を変更することができます。そのためには、次のようにして <code>mark</code> に固有の情報を与えます。</p> + +<pre class="brush: js notranslate">mark.name = 'Doe, Mark'; +mark.dept = 'admin'; +mark.projects = ['navigator'];</pre> + +<h3 id="Adding_properties" name="Adding_properties">プロパティの追加</h3> + +<p>JavaScript では、実行時にどんなオブジェクトにもプロパティを追加することができます。コンストラクター関数で与えられるプロパティだけしか使えないわけではありません。単一のオブジェクトに特化してプロパティを追加するには、次のようにオブジェクトに値を代入します。</p> + +<pre class="brush: js notranslate">mark.bonus = 3000; +</pre> + +<p>すると、<code>mark</code> オブジェクトに <code>bonus</code> プロパティができます。しかし <code>WorkerBee</code> にはこのプロパティは存在しません。</p> + +<p>あるコンストラクター関数のプロトタイプとして使用されているオブジェクトに新しいプロパティを追加すると、プロトタイプからプロパティを継承する全オブジェクトにそのプロパティを追加します。例えば、次の文を使用すると <code>specialty</code> プロパティをすべての従業員に対して追加することができます。</p> + +<pre class="brush: js notranslate">Employee.prototype.specialty = 'none'; +</pre> + +<p>JavaScript でこの文が実行されると、即座に <code>mark</code> オブジェクトも <code>specialty</code> プロパティを <code>"none"</code> という値で持つようになります。次の図では、プロパティを <code>Employee</code> プロトタイプに追加し、さらに <code>Engineer</code> プロトタイプに存在するプロパティを上書きしたときの効果を示しています。</p> + +<p><img alt="" class="internal" src="/@api/deki/files/4422/=figure8.4.png" style="height: 519px; width: 833px;"><br> + <small><strong>プロパティの追加</strong></small></p> + +<h2 id="More_flexible_constructors" name="More_flexible_constructors">より柔軟なコンストラクター</h2> + +<p>これまでに見てきたコンストラクター関数は、インスタンス作成時にプロパティの値を指定することができませんでした。Java のようにコンストラクターに引数を与えて、インスタンスのプロパティの値を初期化することができます。以下の図はこれを実現する方法の一つの方法です。</p> + +<p><img alt="" class="internal" id="figure8.5" src="/@api/deki/files/4423/=figure8.5.png" style="height: 481px; width: 1012px;"><br> + <small><strong>コンストラクターでのプロパティの指定方法、その 1</strong></small></p> + +<p>Java および JavaScript におけるこれらのオブジェクト定義を次表に示します。</p> + +<pre class="brush: js notranslate">function Employee(name, dept) { + this.name = name || ''; + this.dept = dept || 'general'; +} +</pre> + +<pre class="brush: java notranslate">public class Employee { + public String name; + public String dept; + public Employee () { + this("", "general"); + } + public Employee (String name) { + this(name, "general"); + } + public Employee (String name, String dept) { + this.name = name; + this.dept = dept; + } +} +</pre> + +<pre class="brush: js notranslate">function WorkerBee(projs) { + this.projects = projs || []; +} +WorkerBee.prototype = new Employee; +</pre> + +<pre class="brush: java notranslate">public class WorkerBee extends Employee { + public String[] projects; + public WorkerBee () { + this(new String[0]); + } + public WorkerBee (String[] projs) { + projects = projs; + } +} +</pre> + +<pre class="brush: js notranslate"> +function Engineer(mach) { + this.dept = 'engineering'; + this.machine = mach || ''; +} +Engineer.prototype = new WorkerBee; +</pre> + +<pre class="brush: java notranslate">public class Engineer extends WorkerBee { + public String machine; + public Engineer () { + dept = "engineering"; + machine = ""; + } + public Engineer (String mach) { + dept = "engineering"; + machine = mach; + } +} +</pre> + +<p>これらの JavaScript の定義では、既定値の設定に特殊な構文を使用しています。</p> + +<pre class="brush: js notranslate">this.name = name || ''; +</pre> + +<p>JavaScript の論理和 (OR) 演算子 (<code>||</code>) は、その最初の引数を評価します。その引数が true に評価される場合、演算子はその引数を返します。そうでない場合、第2引数の値を返します。したがって、このコードは <code>name</code> が <code>name</code> プロパティの値に使用できる値かどうかを確認します。使用できると確認されれば <code>this.name</code> にその値を設定します。そうでなければ <code>this.name</code> に空文字列をセットします。本章ではこの方法がより簡潔なのでこの構文を使用していますが、一目見ただけでは不可解に思えるかもしれません。</p> + +<div class="note"> +<p><strong>注:</strong> ご想像の通り、この構文はコンストラクターが <code>false</code> に変換される引数(<code>0</code> や空文字列 (<code>""</code>) など)と共に呼び出された場合は動作しません。その場合は既定値が選択されます。</p> +</div> + +<p>これらの定義を用いると、オブジェクトのインスタンスを作成するときに、局所的に定義されたプロパティに対する値を指定することができます。次の文を使用すると新しい <code>Engineer</code> を作成できます。</p> + +<pre class="brush: js notranslate">var jane = new Engineer('belau'); +</pre> + +<p>すると <code>Jane</code> のプロパティは次のようになります。</p> + +<pre class="brush: js notranslate">jane.name == ''; +jane.dept == 'engineering'; +jane.projects == []; +jane.machine == 'belau'; +</pre> + +<p>これらの定義では、<code>name</code> のような継承されたプロパティに対して初期値を指定することはできない点に注意してください。JavaScript で継承されるプロパティに対し初期値を指定したいのであれば、コンストラクター関数にさらにコードを追加する必要があります。</p> + +<p>ここまでは、コンストラクター関数は汎用オブジェクトを生成し、その後で新しいオブジェクトに対してローカルプロパティと値を定義していました。プロトタイプチェーンのより上位のオブジェクトのコンストラクター関数を直接呼び出すことで、コンストラクターへさらにプロパティを追加することができます。次の図はこの新しい定義方法です。</p> + +<p><img alt="" class="internal" src="/@api/deki/files/4430/=figure8.6.png" style="height: 534px; width: 1063px;"><br> + <small><strong>コンストラクターでのプロパティの指定方法、その 2</strong></small></p> + +<p>これらの定義の一つを詳しく見ていきましょう。これは <code>Engineer</code> コンストラクターの新しい定義です。</p> + +<pre class="brush: js notranslate">function Engineer(name, projs, mach) { + this.base = WorkerBee; + this.base(name, 'engineering', projs); + this.machine = mach || ''; +} +</pre> + +<p>次のようにして新しい <code>Engineer</code> オブジェクトを作成するとします。</p> + +<pre class="brush: js notranslate">var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau'); +</pre> + +<p>JavaScript は次の手順を踏みます。</p> + +<ol> + <li><code>new</code> 演算子が汎用オブジェクトを生成し、その <code>__proto__</code> プロパティに <code>Engineer.prototype</code> を設定します。</li> + <li><code>new</code> 演算子が <code>this</code> キーワードの値としてこの新しい汎用オブジェクトを <code>Engineer</code> コンストラクターに渡します。</li> + <li>コンストラクターがそのオブジェクトに <code>base</code> という新しいプロパティを生成し、<code>WorkerBee</code> コンストラクターの値を <code>base</code> プロパティに代入します。これにより、<code>WorkerBee</code> コンストラクターは <code>Engineer</code> オブジェクトのメソッドになります。<code>base</code> というプロパティ名は特別なものではありません。あらゆる正当なプロパティ名を使用できますが、ここで <code>base</code> という名前を使うのは、その目的をたやすくイメージさせるためです。</li> + <li>コンストラクターが <code>base</code> メソッドを呼び出します。その引数として、コンストラクターに渡された引数のうち 2 つ(<code>"Doe, Jane"</code> および <code>["navigator", "javascript"]</code>)と、さらに文字列 <code>"engineering"</code> を渡します。コンストラクターで <code>"engineering"</code> を明示的に使用するのは、すべての <code>Engineer</code> オブジェクトは継承により <code>dept</code> プロパティは同じ値となっていて、<code>Employee</code> から継承された値を指定値に上書きするためです。</li> + <li><code>base</code> は <code>Engineer</code> のメソッドであるため、<code>base</code> を呼び出す際に、JavaScript によって <code>this</code> キーワードをステップ 1 で作成したオブジェクトにバインドします。これにより、<code>WorkerBee</code> 関数は順に <code>"Doe, Jane"</code> および <code>"engineering"</code> という引数を <code>Employee</code> コンストラクター関数に渡します。<code>Employee</code> コンストラクター関数から戻ると、<code>WorkerBee</code> 関数は残りの引数を使用して <code>projects</code> プロパティをセットします。</li> + <li><code>base</code> メソッドから戻ると、<code>Engineer</code> コンストラクターがオブジェクトの <code>machine</code> プロパティを <code>"belau"</code> に初期化します。</li> + <li>コンストラクターから戻ると、JavaScript は新しいオブジェクトを <code>jane</code> という変数に代入します。</li> +</ol> + +<p><code>Engineer</code> コンストラクターの内部から <code>WorkerBee</code> コンストラクターを呼び出しさえすれば、きちんと <code>Engineer</code> オブジェクトに継承が設定されるように思うかもしれません。しかし実際はそうではありません。<code>WorkerBee</code> コンストラクターを呼び出すことで、呼び出されるすべてのコンストラクター関数によって指定されたプロパティを持つ <code>Engineer</code> オブジェクトは確かに作成されます。しかし、後からプロパティを <code>Employee</code> または <code>WorkerBee</code> のプロトタイプに追加しても、それらのプロパティは <code>Engineer</code> オブジェクトに継承されません。例えば、次のような文を書いたとします。</p> + +<pre class="brush: js notranslate">function Engineer(name, projs, mach) { + this.base = WorkerBee; + this.base(name, 'engineering', projs); + this.machine = mach || ''; +} +var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau'); +Employee.prototype.specialty = 'none'; +</pre> + +<p><code>jane</code> オブジェクトは <code>specialty</code> プロパティを継承しません。動的な継承を確実にするには、やはりプロトタイプを明示的に示す必要があります。代わりに次の文を使用しましょう。</p> + +<pre class="brush: js notranslate">function Engineer(name, projs, mach) { + this.base = WorkerBee; + this.base(name, 'engineering', projs); + this.machine = mach || ''; +} +Engineer.prototype = new WorkerBee; +var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau'); +Employee.prototype.specialty = 'none'; +</pre> + +<p>すると、<code>jane</code> オブジェクトの <code>specialty</code> プロパティの値は "none" になります。</p> + +<p>もう一つの継承方法は、<code><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/call" title="ja/docs/JavaScript/Reference/Global Objects/Function/call">call()</a></code> / <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/apply" title="ja/docs/JavaScript/Reference/Global Objects/Function/apply"><code>apply()</code></a> メソッドを使うことです。以下の二つは同等です。</p> + +<pre class="brush: js notranslate">function Engineer(name, projs, mach) { + this.base = WorkerBee; + this.base(name, 'engineering', projs); + this.machine = mach || ''; +} +</pre> + +<pre class="brush: js notranslate">function Engineer(name, projs, mach) { + WorkerBee.call(this, name, 'engineering', projs); + this.machine = mach || ''; +} +</pre> + +<p>JavaScript の <code>call()</code> メソッドを使うことで、実装がよりきれいになります。<code>base</code> が全く必要ないからです。</p> + +<h2 id="Property_inheritance_revisited" name="Property_inheritance_revisited">プロパティの継承、再び</h2> + +<p>これまでの節では、JavaScript のコンストラクターとプロトタイプが階層をどのように実現しているかを説明してきました。この節では、これまでの議論では必ずしも明白ではなかった、細かい部分について議論していきます。</p> + +<h3 id="Local_versus_inherited_values" name="Local_versus_inherited_values">ローカル値と継承値</h3> + +<p>オブジェクトのプロパティにアクセスすると、この章で先に説明したように、JavaScript は次のステップを実行します。</p> + +<ol> + <li>プロパティの値がローカルに存在するかを確かめます。存在している場合は、その値を返します。</li> + <li>値がローカルに存在していない場合は、プロトタイプチェーンを確認します(<code>__proto__</code> プロパティを使用)。</li> + <li>プロトタイプチェーン内のオブジェクトが指定したプロパティの値を持っている場合は、その値を返します。</li> + <li>そのようなプロパティが見つからない場合は、オブジェクトにそのプロパティは存在しません。</li> +</ol> + +<p>このステップの結果は、それまでにどのようにオブジェクトを定義したかによります。元の例では次の定義を用いました。</p> + +<pre class="brush: js notranslate">function Employee() { + this.name = ''; + this.dept = 'general'; +} + +function WorkerBee() { + this.projects = []; +} +WorkerBee.prototype = new Employee; +</pre> + +<p>この定義を前提とし、次の文を用いて <code>WorkerBee</code> のインスタンスとして <code>amy</code> を作成するとします。</p> + +<pre class="brush: js notranslate">var amy = new WorkerBee; +</pre> + +<p><code>amy</code> オブジェクトにはローカルプロパティが 1 つあります。それは <code>projects</code> です。<code>name</code> および <code>dept</code> プロパティの値は <code>amy</code> にとってローカルではないため、<code>amy</code> オブジェクトの <code>__proto__</code> プロパティから取得します。その結果、<code>amy</code> には次のプロパティが存在することになります。</p> + +<pre class="brush: js notranslate">amy.name == ''; +amy.dept == 'general'; +amy.projects == []; +</pre> + +<p>ここで、<code>Employee</code> に結びつけられたプロトタイプの <code>name</code> プロパティの値を変えてみましょう :</p> + +<pre class="brush: js notranslate">Employee.prototype.name = 'Unknown'; +</pre> + +<p>一見、<code>Employee</code> の全インスタンスに新しい値が反映されるように思われます。しかし、そうはなりません。</p> + +<p><code>Employee</code> オブジェクトからなる<em>いかなる</em>インスタンスを作成しても、そのインスタンスは <code>name</code> プロパティのローカル値(空文字列)を持つことになります。つまり、新しい <code>Employee</code> オブジェクトの作成に <code>WorkerBee</code> プロトタイプを設定すれば、<code>WorkerBee.prototype</code> は <code>name</code> プロパティのためのローカル値を持つことになる、ということです。そのため、JavaScript が <code>amy</code> オブジェクト(<code>WorkerBee</code> のインスタンス)の <code>name</code> プロパティを探すと、JavaScript はそのプロパティのローカル値を <code>WorkerBee.prototype</code> 内で発見します。結果、<code>Employee.prototype</code> まではチェーンの検索は行われません。</p> + +<p>実行時にオブジェクトのプロパティの値を変更し、新しい値がそのオブジェクトのすべての子孫に継承するようにしたい場合は、オブジェクトのコンストラクター関数内でそのプロパティを定義してはいけません。その代わりに、コンストラクター関数に結びつけられたプロトタイプにプロパティを追加します。例えば、先のコードを次のように変更しましょう。</p> + +<pre class="brush: js notranslate">function Employee() { + this.dept = 'general'; // Note that this.name (a local variable) does not appear here +} +Employee.prototype.name = ''; // A single copy + +function WorkerBee() { + this.projects = []; +} +WorkerBee.prototype = new Employee; + +var amy = new WorkerBee; + +Employee.prototype.name = 'Unknown'; +</pre> + +<p>こうすれば、<code>amy</code> の <code>name</code> プロパティは "Unknown" になります。</p> + +<p>この例で示したように、オブジェクトのプロパティにデフォルトの値を持たせて、実行時にデフォルト値を変更したいのであれば、コンストラクター関数内でなく、コンストラクターのプロトタイプ内でプロパティを設定するようにしてください。</p> + +<h3 id="Determining_instance_relationships" name="Determining_instance_relationships">インスタンス関係の決定</h3> + +<p>JavaScript でのプロパティ探索は、まずオブジェクト自身のプロパティ内で探索し、そのプロパティ名が存在しない場合は特殊なオブジェクトプロパティである <code>__proto__</code> で探索します。これは再帰的に継続されます。このプロセスを「プロトタイプチェーンの探索」と呼びます。</p> + +<p>この特別なプロパティ <code>__proto__</code> は、オブジェクトが構築される際に設定されて、コンストラクターの <code>prototype</code> プロパティを構成する値となります。よって、式 <code>new Foo()</code> は <code>__proto__ == <code class="moz-txt-verticalline">Foo.prototype</code></code> となるオブジェクトを作成します。その結果、<code class="moz-txt-verticalline">Foo.prototype</code> のプロパティの変更により、<code>new Foo()</code> で作成されたすべてのオブジェクトのプロパティ探索が変更されます。</p> + +<p>すべてのオブジェクトは(<code>Object</code> を除いて) <code>__proto__</code> オブジェクトプロパティを持ちます。また、すべての関数は <code>prototype</code> オブジェクトプロパティを持ちます。したがって、「プロトタイプ継承」を用いてオブジェクトを別のオブジェクトへ関連づけられます。オブジェクトの <code>__proto__</code> と関数の <code>prototype</code> オブジェクトを比較することで、継承状態の確認ができます。これを行う手っ取り早い方法が JavaScript にはあります。<code>instanceof</code> 演算子はオブジェクトと関数を検査して、オブジェクトが関数のプロトタイプから継承している場合に true を返します。例えば、</p> + +<pre class="brush: js notranslate">var f = new Foo(); +var isTrue = (f instanceof Foo);</pre> + +<p>もっと詳しい例として、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Details_of_the_Object_Model%24edit#Inheriting_properties">プロパティの継承</a>で利用した定義を使ってみましょう。以下のようにして <code>Engineer</code> オブジェクトを作成しましょう。</p> + +<pre class="brush: js notranslate">var chris = new Engineer('Pigman, Chris', ['jsd'], 'fiji'); +</pre> + +<p>このオブジェクトでは、以下の文はすべて true になります。</p> + +<pre class="brush: js notranslate">chris.__proto__ == Engineer.prototype; +chris.__proto__.__proto__ == WorkerBee.prototype; +chris.__proto__.__proto__.__proto__ == Employee.prototype; +chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype; +chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null; +</pre> + +<p>ここで次のような <code>instanceOf</code> 関数を書いてみましょう。</p> + +<pre class="brush: js notranslate">function instanceOf(object, constructor) { + object = object.__proto__; + while (object != null) { + if (object == constructor.prototype) + return true; + if (typeof object == 'xml') { + return constructor.prototype == XML.prototype; + } + object = object.__proto__; + } + return false; +} +</pre> + +<div class="note"><strong>注: </strong> 上記の実装では、最近のバージョンでの JavaScript における XML オブジェクト表現法の癖を回避するために、オブジェクトの型と "xml" とを照合しています。具体的な詳細を知りたい場合は {{bug(634150)}} をご覧ください。</div> + +<p>この定義を用いると、以下の式はすべて true になります。</p> + +<pre class="brush: js notranslate">instanceOf(chris, Engineer) +instanceOf(chris, WorkerBee) +instanceOf(chris, Employee) +instanceOf(chris, Object) +</pre> + +<p>しかし、次の式は false になります :</p> + +<pre class="brush: js notranslate">instanceOf(chris, SalesPerson) +</pre> + +<h3 id="Global_information_in_constructors" name="Global_information_in_constructors">コンストラクターにおけるグローバル情報</h3> + +<p>コンストラクターを作成する際、コンストラクター内でグローバルな情報を設定する場合は注意が必要です。例えば、一意的な ID をそれぞれの新しい従業員情報へ自動的に代入したいとします。そこで、以下のように <code>Employee</code> を定義できます :</p> + +<pre class="brush: js notranslate">var idCounter = 1; + +function Employee(name, dept) { + this.name = name || ''; + this.dept = dept || 'general'; + this.id = idCounter++; +} +</pre> + +<p>この定義を用いると、新しい <code>Employee</code> を作成するたびに、コンストラクターが次の ID を順々に代入し、グローバルな ID カウンターをインクリメントします。その結果、続けて以下の文を置くと <code>victoria.id</code> は 1 に、<code>harry.id</code> は 2 となります :</p> + +<pre class="brush: js notranslate">var victoria = new Employee('Pigbert, Victoria', 'pubs'); +var harry = new Employee('Tschopik, Harry', 'sales'); +</pre> + +<p>一見、これは申し分なさそうです。しかし、<code>idCounter</code> はどのような用途であろうと、<code>Employee</code> オブジェクトが作成されるたびにインクリメントされます。この章で示した <code>Employee</code> の階層全体を作成すると、<code>Employee</code> コンストラクターはプロトタイプをセットアップするたびに呼び出されます。次のようなコードがあるとします :</p> + +<pre class="brush: js notranslate">var idCounter = 1; + +function Employee(name, dept) { + this.name = name || ''; + this.dept = dept || 'general'; + this.id = idCounter++; +} + +function Manager(name, dept, reports) {...} +Manager.prototype = new Employee; + +function WorkerBee(name, dept, projs) {...} +WorkerBee.prototype = new Employee; + +function Engineer(name, projs, mach) {...} +Engineer.prototype = new WorkerBee; + +function SalesPerson(name, projs, quota) {...} +SalesPerson.prototype = new WorkerBee; + +var mac = new Engineer('Wood, Mac'); +</pre> + +<p>さらに、ここでは省かれている定義に <code>base</code> プロパティがあり、その定義がプロトタイプチェーンにおいて上位のコンストラクターを呼び出すとします。この場合、<code>mac</code> オブジェクトが作成されるまでに <code>mac.id</code> は 5 になってしまいます。</p> + +<p>カウンターが余計にインクリメントされることが問題になるかどうかは、そのアプリケーション次第です。このカウンターの正確な値を気にするのであれば、代わりに一つの解決策として以下のようなコンストラクターが考えられます。</p> + +<pre class="brush: js notranslate">function Employee(name, dept) { + this.name = name || ''; + this.dept = dept || 'general'; + if (name) + this.id = idCounter++; +} +</pre> + +<p>プロトタイプとして使用する <code>Employee</code> のインスタンスを作成するときに、コンストラクターに引数を与えてはいけません。このコンストラクターの定義を使用すれば、引数を渡さないときはコンストラクターが ID に値を代入せず、カウンターの更新も行いません。そのため、割り当てられる id を <code>Employee</code> に付与したい場合は、従業員の名前を指定する必要があります。この例では <code>mac.id</code> は 1 になります。</p> + +<p>それ以外に、WorkerBee に割り当てるために Employee のプロトタイプオブジェクトのコピーを作成することもできます。</p> + +<pre class="brush: js notranslate">WorkerBee.prototype = Object.create(Employee.prototype); +// instead of WorkerBee.prototype = new Employee +</pre> + +<h3 id="No_multiple_inheritance" name="No_multiple_inheritance">多重継承はなし</h3> + +<p>オブジェクト指向言語の中には、多重継承を許容するものがあります。つまり、オブジェクトが無関係な親オブジェクトから、プロパティと値を継承できるということです。JavaScript は多重継承をサポートしていません。</p> + +<p>実行時のプロパティの値の継承は、JavaScript が値を見つけようとしてオブジェクトのプロトタイプチェーンを探索することで行われます。オブジェクトに結びつけられたプロトタイプは 1 つであるため、JavaScript は複数のプロトタイプチェーンから動的に継承することはできません。</p> + +<p>JavaScript では、コンストラクター関数がその中で複数の別のコンストラクター関数を呼び出すようにすることができます。これによって多重継承状のものが実現できます。例えば以下の文があるとします。</p> + +<pre class="brush: js notranslate">function Hobbyist(hobby) { + this.hobby = hobby || 'scuba'; +} + +function Engineer(name, projs, mach, hobby) { + this.base1 = WorkerBee; + this.base1(name, 'engineering', projs); + this.base2 = Hobbyist; + this.base2(hobby); + this.machine = mach || ''; +} +Engineer.prototype = new WorkerBee; + +var dennis = new Engineer('Doe, Dennis', ['collabra'], 'hugo'); +</pre> + +<p>さらに、<code>WorkerBee</code> の定義はこの章で先に使用したものであるとします。この場合、<code>dennis</code> オブジェクトにはこれらのプロパティが存在します。</p> + +<pre class="brush: js notranslate">dennis.name == 'Doe, Dennis'; +dennis.dept == 'engineering'; +dennis.projects == ['collabra']; +dennis.machine == 'hugo'; +dennis.hobby == 'scuba'; +</pre> + +<p><code>dennis</code> は <code>Hobbyist</code> コンストラクターから <code>hobby</code> プロパティを取得しているのです。ここで、<code>Hobbyist</code> コンストラクターのプロトタイプにプロパティを追加してみましょう。</p> + +<pre class="brush: js notranslate">Hobbyist.prototype.equipment = ['mask', 'fins', 'regulator', 'bcd']; +</pre> + +<p>このようにしても <code>dennis</code> オブジェクトはこの新しいプロパティを継承しません。</p> + +<div>{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Using_promises")}}</div> diff --git a/files/ja/web/javascript/guide/exception_handling_statements/index.html b/files/ja/web/javascript/guide/exception_handling_statements/index.html new file mode 100644 index 0000000000..fddf6c4181 --- /dev/null +++ b/files/ja/web/javascript/guide/exception_handling_statements/index.html @@ -0,0 +1,36 @@ +--- +title: 例外処理文 +slug: Web/JavaScript/Guide/Exception_Handling_Statements +--- +<h3 id=".E4.BE.8B.E5.A4.96.E5.87.A6.E7.90.86.E6.96.87" name=".E4.BE.8B.E5.A4.96.E5.87.A6.E7.90.86.E6.96.87">例外処理文</h3> +<p><code>throw</code> 文を使用すると例外を投げることができます。また、<code>try...catch</code> 文を使用すると例外を処理することができます。</p> +<p><code>try...catch</code> 文を使用して Java の例外を処理することもできます。この情報については <a href="/ja/Core_JavaScript_1.5_Guide/LiveConnect_Overview/JavaScript_to_Java_Communication#JavaScript_.E3.81.A7.E3.81.AE_Java_.E3.81.AE.E4.BE.8B.E5.A4.96.E3.81.AE.E5.87.A6.E7.90.86" title="ja/Core_JavaScript_1.5_Guide/LiveConnect_Overview/JavaScript_to_Java_Communication#JavaScript_.E3.81.A7.E3.81.AE_Java_.E3.81.AE.E4.BE.8B.E5.A4.96.E3.81.AE.E5.87.A6.E7.90.86">JavaScript での Java の例外の処理</a> および <a href="/ja/Core_JavaScript_1.5_Guide/LiveConnect_Overview/JavaScript_to_Java_Communication" title="ja/Core_JavaScript_1.5_Guide/LiveConnect_Overview/JavaScript_to_Java_Communication">Java と JavaScript との通信</a> をご覧ください。</p> +<ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Exception_Handling_Statements/throw_Statement" title="ja/Core_JavaScript_1.5_Guide/Exception_Handling_Statements/throw_Statement">throw 文</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Exception_Handling_Statements/try...catch_Statement" title="ja/Core_JavaScript_1.5_Guide/Exception_Handling_Statements/try...catch_Statement">try...catch 文</a></li> +</ul> +<h3 id=".E4.BE.8B.E5.A4.96.E3.81.AE.E7.A8.AE.E9.A1.9E" name=".E4.BE.8B.E5.A4.96.E3.81.AE.E7.A8.AE.E9.A1.9E">例外の種類</h3> +<p>JavaScript ではほとんどどんなオブジェクトでも投げることができます。とは言っても、必ずしもすべての投げられたオブジェクトが同等に作られているわけではありません。数値や文字列をエラーとして投げる方法はよく用いられますが、特にこの用途のために作られている例外の種類のうちのどれかを使用したほうがより効率的であることがよくあります。</p> +<ul> + <li>ECMAScript の例外 + <ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Error" title="ja/Core_JavaScript_1.5_Guide/Error">Error</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/EvalError" title="ja/Core_JavaScript_1.5_Guide/EvalError">EvalError</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/RangeError" title="ja/Core_JavaScript_1.5_Guide/RangeError">RangeError</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/ReferenceError" title="ja/Core_JavaScript_1.5_Guide/ReferenceError">ReferenceError</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/SyntaxError" title="ja/Core_JavaScript_1.5_Guide/SyntaxError">SyntaxError</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/TypeError" title="ja/Core_JavaScript_1.5_Guide/TypeError">TypeError</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/URIError" title="ja/Core_JavaScript_1.5_Guide/URIError">URIError</a></li> + </ul> + </li> + <li>DOM の例外 + <ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/DOMException" title="ja/Core_JavaScript_1.5_Guide/DOMException">DOMException</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/EventException" title="ja/Core_JavaScript_1.5_Guide/EventException">EventException</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/RangeException" title="ja/Core_JavaScript_1.5_Guide/RangeException">RangeException</a></li> + <li>... (?)</li> + </ul> + </li> + <li><a href="/ja/NsIXPCException" title="ja/NsIXPCException">nsIXPCException</a> (<a href="/ja/XPConnect" title="ja/XPConnect">XPConnect</a>)</li> +</ul> +<p>{{ PreviousNext("JavaScript/Guide/Comments", "JavaScript/Guide/Exception_Handling_Statements/throw_Statement") }}</p> diff --git a/files/ja/web/javascript/guide/exception_handling_statements/throw_statement/index.html b/files/ja/web/javascript/guide/exception_handling_statements/throw_statement/index.html new file mode 100644 index 0000000000..9d98321883 --- /dev/null +++ b/files/ja/web/javascript/guide/exception_handling_statements/throw_statement/index.html @@ -0,0 +1,34 @@ +--- +title: throw 文 +slug: Web/JavaScript/Guide/Exception_Handling_Statements/throw_Statement +--- +<h3 id="throw_.E6.96.87" name="throw_.E6.96.87">throw 文</h3> +<p><code>throw</code> 文は例外を投げるために使用します。例外を投げるときは、投げたい値からなる式を指定してください。</p> +<pre class="eval">throw expression; +</pre> +<p>特定の型の式だけではなく、あらゆる式を投げることができます。下記のコードは様々な型の例外を投げています。</p> +<pre class="eval">throw "Error2"; +throw 42; +throw true; +throw {toString: function() { return "I'm an object!"; } }; +</pre> +<div class="note"> + <strong>注意:</strong>例外を投げる際にオブジェクトを指定することができます。すると、<code>catch</code> ブロックでそのオブジェクトのプロパティを参照できるようになります。次の例では <code>UserException</code> という種類の <code>myUserException</code> というオブジェクトを作ります。また、このオブジェクトを throw 文で使用します。</div> +<pre class="eval">// UserException という種類のオブジェクトを作成 +function UserException (message) +{ + this.message=message; + this.name="UserException"; +} + +// 文字列として使用されるとき(例:エラーコンソール上)に +// 例外を整形する +UserException.prototype.toString = function () +{ + return this.name + ': "' + this.message + '"'; +} + +// そのオブジェクトの種類のインスタンスを作成し、それを投げる +throw new UserException("Value too high"); +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Exception_Handling_Statements", "JavaScript/Guide/Exception_Handling_Statements/try...catch_Statement") }}</p> diff --git a/files/ja/web/javascript/guide/exception_handling_statements/try...catch_statement/index.html b/files/ja/web/javascript/guide/exception_handling_statements/try...catch_statement/index.html new file mode 100644 index 0000000000..678cd3f38e --- /dev/null +++ b/files/ja/web/javascript/guide/exception_handling_statements/try...catch_statement/index.html @@ -0,0 +1,135 @@ +--- +title: try...catch 文 +slug: Web/JavaScript/Guide/Exception_Handling_Statements/try...catch_Statement +--- +<h3 id="try...catch_.E6.96.87" name="try...catch_.E6.96.87">try...catch 文</h3> + +<p><code>try...catch</code> 文はテストしたい文のブロックを指定し、さらに投げられるであろう例外に対する 1 つ以上の対処方法を指定します。例外が投げられると <code>try...catch</code> 文がそれを受け取ります。</p> + +<p><code>try...catch</code> 文は 1 つの <code>try</code> ブロックと 0 個以上の <code>catch</code> ブロックからなります。前者は 1 つ以上の文からなります。後者は try ブロックで例外が投げられた場合にどうするかを指定する文からなります。すなわち、成功させたい <code>try</code> ブロックと、失敗した場合にコントロールを渡す <code>catch</code> ブロックからなります。<code>try</code> ブロック内(もしくは <code>try</code> ブロック内から呼び出された関数内)のいずれかの文が例外を投げた場合、コントロールはすぐに <code>catch</code> ブロックに移ります。<code>try</code> ブロックで例外が投げられなかった場合は <code>catch</code> ブロックは飛ばされます。<code>finally</code> ブロックは <code>try</code> および <code>catch</code> ブロックが実行された後に実行されます。ただし <code>try...catch</code> 文の後に続く文より先に実行されます。</p> + +<p>次の例では <code>try...catch</code> 文を使用しています。この例では渡された値に基づいて配列から月の名前を取り出す関数を呼び出します。値に対応する月の数字 (1-12) がなかったら、<code>InvalidMonthNo</code> という値を持つ例外が投げられ、<code>catch</code> ブロックの中の文は <code>monthName</code> という変数に <code>unknown</code> という値をセットします。</p> + +<pre>function getMonthName (mo) { + mo=mo-1; // 月の数字を配列のインデックスに合わせる (1=Jan, 12=Dec) + var months=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul", + "Aug","Sep","Oct","Nov","Dec"); + if (months[mo] != null) { + return months[mo] + } else { + throw "InvalidMonthNo" + } +} + +try { +// テストする文 + monthName=getMonthName(myMonth) // 関数は例外を投げることがある +} +catch (e) { + monthName="unknown" + logMyErrors(e) // 例外オブジェクトをエラー処理部分に渡す +} +</pre> + +<h4 id="catch_.E3.83.96.E3.83.AD.E3.83.83.E3.82.AF" name="catch_.E3.83.96.E3.83.AD.E3.83.83.E3.82.AF">catch ブロック</h4> + +<p>単一の <code>catch</code> ブロックを使用すると、<code>try</code> ブロックで生じうるすべての例外を扱うことができます。また、扱う例外の種類によって <code>catch</code> ブロックをそれぞれに分けることもできます。</p> + +<p><strong>単一の catch ブロック</strong><br> + <code>try</code> ブロックで投げられるいかなる例外にも対応したエラー処理コードを実行するには、<code>try...catch</code> 文で <code>catch</code> を 1 つ使用してください。</p> + +<p>単一の <code>catch</code> ブロックは次のように使用します。</p> + +<pre>catch (catchID) { + statements +} +</pre> + +<p><code>catch</code> ブロックは、<code>throw</code> 文で指定された値を持つ識別子(上記の構文における <code>catchID</code>)を指定します。この識別子を使用することで投げられた例外についての情報を得ることができます。JavaScript は <code>catch</code> ブロックに入るときにこの識別子を作成します。識別子は <code>catch</code> ブロックにいる間だけ持続します。つまり、<code>catch</code> ブロックの実行が終了するとその識別子はもう使えなくなります。</p> + +<p>例えば、次のコードは例外を投げます。例外が生じるとコントロールが <code>catch</code> ブロックに移ります。</p> + +<pre>try { + throw "myException" // 例外を生成 +} +catch (e) { +// どんな例外も扱う文 + logMyErrors(e) // 例外オブジェクトをエラー処理部分に渡す +} +</pre> + +<p><strong>複数の catch ブロック</strong><br> + 1 つの <code>try</code> 文に対して、複数の条件についての <code>catch</code> ブロックを使うことができます。そして、そのそれぞれがそれぞれの種類の例外を担当します。この場合、そのブロックで指定されている例外が投げられたときだけ、適切な条件の <code>catch</code> ブロックに入ることになります。すべての未指定の例外のために、すべての例外に対応した <code>catch</code> ブロックをその文の最後の catch ブロックとしてオプション的に設けることもできます。</p> + +<p>例えば、次の関数は 3 つの別の関数(どこかで定義済み)を呼び出します。この関数はその引数が妥当であるかを確かめます。妥当性確認関数が確認対象の構成要素が妥当でないと決定した場合、その関数は 0 を返し、該当する例外を呼び出し元に投げさせます。</p> + +<pre>function getCustInfo(name, id, email) +{ + var n, i, e; + + if (!validate_name(name)) + throw "InvalidNameException" + else + n = name; + if (!validate_id(id)) + throw "InvalidIdException" + else + i = id; + if (!validate_email(email)) + throw "InvalidEmailException" + else + e = email; + cust = (n + " " + i + " " + e); + return (cust); +} +</pre> + +<p>おのおのの条件の <code>catch</code> ブロックは適当な例外処理部分にコントロールを渡します。</p> + +<pre>try { +// 関数は 3 つの例外を投げうる + getCustInfo("Lee", 1234, "lee@netscape.com") +} + +catch (e if e == "InvalidNameException") { +// 不正な名前に対しての処理部分を呼び出す + bad_name_handler(e) +} + +catch (e if e == "InvalidIdException") { +// 不正な ID に対しての処理部分を呼び出す + bad_id_handler(e) +} + +catch (e if e == "InvalidEmailException") { +// 不正なメールアドレスに対しての処理部分を呼び出す + bad_email_handler(e) +} + +catch (e){ +// 何が起きるかはわからないが、そのログをとる + logError(e) +} +</pre> + +<h4 id="finally_.E3.83.96.E3.83.AD.E3.83.83.E3.82.AF" name="finally_.E3.83.96.E3.83.AD.E3.83.83.E3.82.AF">finally ブロック</h4> + +<p><code>finally</code> ブロックは、try および catch ブロックの実行が終わった後に実行される文からなります。ただし <code>try...catch</code> 文の後に続く文より前に実行されます。<code>finally</code> ブロックは例外が投げられても投げられなくても実行されます。例外が投げられた場合、<code>finally</code> ブロック内の文はたとえ例外処理をする catch ブロックがなくても実行されます。</p> + +<p><code>finally</code> ブロックを使用することで、例外発生時に適切にスクリプトを停止させることができます。例えば、スクリプトで使用していたリソースを解放する必要があるかもしれません。次の例ではファイルを開き、そのファイルを使用する文を実行します(サーバサイド JavaScript ではファイルにアクセスできます)。ファイルを開いている間に例外が投げられると、スクリプトが停止する前に <code>finally</code> ブロックがそのファイルを閉じます。</p> + +<pre>openMyFile(); +try { + writeMyFile(theData); // エラーを投げる可能性がある +} catch(e) { + handleError(e); // エラーを受け取り、それを処理する +} finally { + closeMyFile(); // 常にリソースを閉じる +} +</pre> + +<h4 id="try...catch_.E6.96.87.E3.81.AE.E3.83.8D.E3.82.B9.E3.83.88" name="try...catch_.E6.96.87.E3.81.AE.E3.83.8D.E3.82.B9.E3.83.88">try...catch 文のネスト</h4> + +<p>1 つ以上の <code>try...catch</code> 文を入れ子にすることができます。内側の <code>try...catch</code> 文に catch ブロックがない場合、囲んでいる <code>try...catch</code> 文の catch ブロックがマッチしているか確認されます。</p> + +<p>{{ PreviousNext("JavaScript/Guide/Exception_Handling_Statements/throw_Statement", "JavaScript/Guide/Defining_Functions") }}</p> diff --git a/files/ja/web/javascript/guide/expressions/index.html b/files/ja/web/javascript/guide/expressions/index.html new file mode 100644 index 0000000000..4feb2b1aa8 --- /dev/null +++ b/files/ja/web/javascript/guide/expressions/index.html @@ -0,0 +1,16 @@ +--- +title: Expressions +slug: Web/JavaScript/Guide/Expressions +--- +<div>{{ 英語版章題("Expressions") }}</div> +<h2 id="式">式</h2> +<p><em>式</em>とは、リテラル、変数、演算子、そして単一の値に評価する式からなる有効なセットです。この値には数値、文字列、論理値が使用できます。</p> +<p>概念的に、式は 2 つの種類に分けることができます。ある値を変数に代入するものと、単純にある値を持つものです。例えば、<code>x = 7</code> という式は x に 7 という値を代入する式です。この式自体の評価結果は 7 です。このような式では<em>代入演算子</em>を用います。一方、<code>3 + 4</code> という式では単純に評価結果が 7 になります。この式は代入を行いません。このような式で用いられる演算子は単に<em>演算子</em>と呼ばれます。</p> +<p>JavaScript には以下の種類の式があります。</p> +<ul> + <li>算術式:数値に評価する。例えば 3.14159。(一般に <a href="/ja/Core_JavaScript_1.5_Guide/Operators/Arithmetic_Operators" title="ja/Core_JavaScript_1.5_Guide/Operators/Arithmetic_Operators">算術演算子</a> を使用)</li> + <li>文字列式:文字列に評価する。例えば "Fred" や "234"。(一般に <a href="/ja/Core_JavaScript_1.5_Guide/Operators/String_Operators" title="ja/Core_JavaScript_1.5_Guide/Operators/String_Operators">文字列演算子</a> を使用)</li> + <li>論理式:true または false に評価する。(よく <a href="/ja/Core_JavaScript_1.5_Guide/Operators/Logical_Operators" title="ja/Core_JavaScript_1.5_Guide/Operators/Logical_Operators">論理演算子</a> を用いる)</li> + <li>オブジェクト式:オブジェクトに評価する。(オブジェクトに評価するさまざまな例については <a href="/ja/Core_JavaScript_1.5_Guide/Operators/Special_Operators" title="ja/Core_JavaScript_1.5_Guide/Operators/Special_Operators">特殊演算子</a> を参照)</li> +</ul> +<p>{{ PreviousNext("JavaScript/Guide/Unicode", "JavaScript/Guide/Operators") }}</p> diff --git a/files/ja/web/javascript/guide/expressions_and_operators/index.html b/files/ja/web/javascript/guide/expressions_and_operators/index.html new file mode 100644 index 0000000000..884497548c --- /dev/null +++ b/files/ja/web/javascript/guide/expressions_and_operators/index.html @@ -0,0 +1,928 @@ +--- +title: 式と演算子 +slug: Web/JavaScript/Guide/Expressions_and_Operators +tags: + - Beginner + - Expressions + - Guide + - JavaScript + - Operators + - 'l10n:priority' + - 演算子 +translation_of: Web/JavaScript/Guide/Expressions_and_Operators +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}}</div> + +<p class="summary">この章では 代入、比較、算術、ビット、論理、文字列、三項演算子などに関わる JavaScript の式 (expression) や演算子 (operator) について説明しています。</p> + +<p>演算子と式について網羅した詳しいリストは<a href="/ja/docs/Web/JavaScript/Reference/Operators">リファレンス</a>でもご覧いただけます。</p> + +<h2 id="Operators" name="Operators">演算子</h2> + +<p>JavaScript では以下の種類の演算子を使用できます。この節では演算子の優先順位についての説明も含めて演算子について説明します。</p> + +<ul> + <li>{{web.link("#Assignment_operators", "代入演算子")}}</li> + <li>{{web.link("#Comparison_operators", "比較演算子")}}</li> + <li>{{web.link("#Arithmetic_operators", "算術演算子")}}</li> + <li>{{web.link("#Bitwise_operators", "ビット演算子")}}</li> + <li>{{web.link("#Logical_operators", "論理演算子")}}</li> + <li>{{web.link("#String_operators", "文字列演算子")}}</li> + <li>{{web.link("#Conditional_(ternary)_operator", "条件(三項)演算子")}}</li> + <li>{{web.link("#Comma_operator", "カンマ演算子")}}</li> + <li>{{web.link("#Unary_operators", "単項演算子")}}</li> + <li>{{web.link("#Relational_operators", "関係演算子")}}</li> +</ul> + +<p>JavaScript は<em>二項演算子</em>や<em>単項演算子</em>を実装しており、さらには三項演算子や条件演算子も実装しています。二項演算子は以下のような形で演算子 (operator) を一つ、その前後となるようにオペランド (operand) が二つ必要となります。</p> + +<pre class="syntaxbox notranslate"><em>operand1</em> <em>operator</em> <em>operand2</em> +</pre> + +<p>例えば <code>3+4</code> や <code>x*y</code> です。</p> + +<p>単項演算子は演算子の前後いずれかに、一つのオペランドが必要です。</p> + +<pre class="syntaxbox notranslate">operator operand</pre> + +<p>もしくは</p> + +<pre class="syntaxbox notranslate">operand operator</pre> + +<p>例えば <code>x++</code> や <code>++x</code> です。</p> + +<h3 id="Assignment_operators" name="Assignment_operators">代入演算子</h3> + +<p>代入演算子は右オペランドの値を元に、左のオペランドへ値を代入するものです。簡単なものでは equal (<code>=</code>) があり、右オペランドの値を左オペランドへ代入します。つまり、<code>x = y</code> では <code>y</code> の値を <code>x</code> へ代入することになります。</p> + +<p>次の表にまとめられているように演算子を省略した複合代入演算子というものもあります。</p> + +<table class="standard-table"> + <caption>複合代入演算子</caption> + <thead> + <tr> + <th>名称</th> + <th>略記演算子</th> + <th>意味</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Assignment">代入</a></td> + <td><code>x = y</code></td> + <td><code>x = y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Addition_assignment">加算代入</a></td> + <td><code>x += y</code></td> + <td><code>x = x + y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Subtraction_assignment">減算代入</a></td> + <td><code>x -= y</code></td> + <td><code>x = x - y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Multiplication_assignment">乗算代入</a></td> + <td><code>x *= y</code></td> + <td><code>x = x * y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Division_assignment">除算代入</a></td> + <td><code>x /= y</code></td> + <td><code>x = x / y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Remainder_assignment">剰余代入</a></td> + <td><code>x %= y</code></td> + <td><code>x = x % y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Exponentiation_assignment">べき乗代入</a></td> + <td><code>x **= y</code></td> + <td><code>x = x ** y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Left_shift_assignment">左シフト代入</a></td> + <td><code>x <<= y</code></td> + <td><code>x = x << y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Right_shift_assignment">右シフト代入</a></td> + <td><code>x >>= y</code></td> + <td><code>x = x >> y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment">符号なし右シフト代入</a></td> + <td><code>x >>>= y</code></td> + <td><code>x = x >>> y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_AND_assignment">ビット論理積 (AND) 代入</a></td> + <td><code>x &= y</code></td> + <td><code>x = x & y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment">ビット排他的論理和 (XOR) 代入</a></td> + <td><code>x ^= y</code></td> + <td><code>x = x ^ y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_OR_assignment">ビット論理和 (OR) 代入</a></td> + <td><code>x |= y</code></td> + <td><code>x = x | y</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment">論理積代入</a></td> + <td><code>x &&= y</code></td> + <td><code>x && (x = y)</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment">論理和代入</a></td> + <td><code>x ||= y</code></td> + <td><code>x || (x = y)</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment">Null 合体代入</a></td> + <td><code>x ??= y</code></td> + <td><code>x ?? (x = y)</code></td> + </tr> + </tbody> +</table> + +<h4 id="Destructuring" name="Destructuring">戻り値と連鎖</h4> + +<p>ほとんどの式と同様に、<code>x = y</code> のような代入には戻り値があります。戻り値は式の代入やロギング等により取得することができます。</p> + +<pre class="notranslate">const z = (x = y); // 右記と等価 const z = x = y; + +console.log(z); // 代入 x = y の戻り値をログする。 +console.log(x = y); // または、戻り値を直接ログする。</pre> + +<p>戻り値は上の表の「意味」列の <code>=</code> 記号の右側の式と一致します。つまり <code>(x = y)</code> は <code>y</code> を返し、<code>(x += y)</code> は加算 <code>x + y</code> の結果を返し、<code>(x **= y)</code> はべき乗 <code>x ** y</code> の結果を返します。</p> + +<p>論理代入、<code>(x &&= y)</code> 、<code>(x ||= y)</code> および <code>(x ??= y)</code> の場合、戻り値は代入を除いた論理演算の結果であり、それぞれ <code>x && y</code> 、<code>x || y</code> および <code>x ?? y</code> を返します。</p> + +<p>戻り値は常に演算<em>前</em>のオペランドの値に基づくことに注意してください。</p> + +<p>これらの式を連鎖させると、それぞれの代入は<strong>右から左に</strong>評価されます。以下の例で考えてみましょう。</p> + +<ul> + <li><code>w = z = x = y</code> は <code>w = (z = (x = y))</code> または <code>x = y; z = y; w = y</code> と等価です</li> + <li><code>z += x *= y</code> は <code>z += (x *= y)</code> または <code>tmp = x * y; x *= y; z += tmp</code>(<code>tmp</code> がないことを除く)と等価です</li> +</ul> + +<h4 id="Destructuring" name="Destructuring">分割代入</h4> + +<p>より複雑な代入方法、<a href="/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">分割代入</a>構文は、配列やオブジェクトのリテラル構造を反映した構文を用いて、配列やオブジェクトからデータを抽出することができる JavaScript の式です。</p> + +<ul> +</ul> + +<ul> +</ul> + +<pre class="brush: js notranslate">var foo = ['one', 'two', 'three']; + +// 分割を行わない代入 +var one = foo[0]; +var two = foo[1]; +var three = foo[2]; + +// 分割代入 +var [one, two, three] = foo;</pre> + +<h3 id="Comparison_operators" name="Comparison_operators">比較演算子</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Comparison_Operators">比較演算子</a>は被演算子を比較して、その結果が真であるかに基づいて論理値を返します。被演算子には数値、文字列、論理値、オブジェクトを使用できます。文字列は Unicode を用い、標準的な辞書順に基づいて比較されます。ほとんどの場合、2 つの被演算子が異なる型ならば JavaScript はその被演算子を比較に適した型に変換しようとします。こうした挙動により、一般的に被演算子は数値的に比較される結果となります。このルールの唯一の例外は <code>===</code> および <code>!==</code> で、これらは「厳密に」等値か否かを判断し、等値性をチェックする前に被演算子を適合する型に変換しません。次の表では、以下のサンプルコードで定義された変数を前提として比較演算子を説明していきます。</p> + +<pre class="brush: js notranslate">var var1 = 3; +var var2 = 4; +</pre> + +<table class="standard-table"> + <caption>比較演算子</caption> + <thead> + <tr> + <th scope="col">演算子</th> + <th scope="col">説明</th> + <th scope="col">true を返す例</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Equality">等価</a> (<code>==</code>)</td> + <td>被演算子が等しい場合に <code>true</code> を返します。</td> + <td><code>3 == var1</code> + <p><code>"3" == var1</code></p> + <code>3 == '3'</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Inequality">不等価</a> (<code>!=</code>)</td> + <td>被演算子が等しくない場合に <code>true</code> を返します。</td> + <td><code>var1 != 4<br> + var2 != "3"</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Strict_equality">厳密等価</a> (<code>===</code>)</td> + <td>被演算子が等しく、かつ同じ型である場合に <code>true</code> を返します。{{jsxref("Object.is")}} や <a href="/ja/docs/Web/JavaScript/Equality_comparisons_and_sameness" title="/ja/docs/Web/JavaScript/Guide/Sameness">JavsScript での等価</a>も参照してください。</td> + <td><code>3 === var1</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Strict_inequality">厳密不等価</a> (<code>!==</code>)</td> + <td>被演算子が等しくなく、かつ/または同じ型でない場合に <code>true</code> を返します。</td> + <td><code>var1 !== "3"<br> + 3 !== '3'</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Greater_than">より大きい</a> (<code>></code>)</td> + <td>左の被演算子が右の被演算子よりも大きい場合に <code>true</code> を返します。</td> + <td><code>var2 > var1<br> + "12" > 2</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal">以上</a> (<code>>=</code>)</td> + <td>左の被演算子が右の被演算子以上である場合に <code>true</code> を返します。</td> + <td><code>var2 >= var1<br> + var1 >= 3</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Less_than">より小さい</a> (<code><</code>)</td> + <td>左の被演算子が右の被演算子よりも小さい場合に <code>true</code> を返します。</td> + <td><code>var1 < var2<br> + "2" < 12</code></td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal">以下</a> (<code><=</code>)</td> + <td>左の被演算子が右の被演算子以下である場合に <code>true</code> を返します。</td> + <td><code>var1 <= var2<br> + var2 <= 5</code></td> + </tr> + </tbody> +</table> + +<div class="note"> +<p><strong>メモ: </strong>(<strong>=></strong>) は演算子ではなく、<a href="/docs/Web/JavaScript/Reference/Functions/Arrow_functions">アロー関数</a>を表す記法です。</p> +</div> + +<h3 id="Arithmetic_operators" name="Arithmetic_operators">算術演算子</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators">算術演算子</a>は被演算子として数値(リテラルまたは変数)をとり、1 つの数値を返します。標準的な算術演算子は、加算 (<code>+</code>)、減算 (<code>-</code>)、乗算 (<code>*</code>)、除算 (<code>/</code>) です。これらの演算子は、他のほとんどのプログラミング言語で浮動小数点数を用いた場合と同じように機能します(特に、0 で除算をすると {{jsxref("Infinity")}} になることに注意してください)。例えば以下のようになります。</p> + +<pre class="brush: js notranslate">1 / 2; // 0.5 +1 / 2 == 1.0 / 2.0; // true になります +</pre> + +<p>標準的な算術演算子に加え、さらに JavaScript では、以下の表で示す算術演算子も使用できます。</p> + +<table class="fullwidth-table"> + <caption>算術演算子</caption> + <thead> + <tr> + <th scope="col">演算子</th> + <th scope="col">説明</th> + <th scope="col">例</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder">剰余</a> (<code>%</code>)</td> + <td>二項演算子です。2 つの被演算子で除算したときの、整数の余りを返します。</td> + <td>12 % 5 は 2 を返します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Increment">インクリメント</a> (<code>++</code>)</td> + <td>単項演算子です。被演算子に 1 を加えます。前置演算子 (<code>++x</code>) として用いると、被演算子に 1 を加えた後にその値を返します。後置演算子 (<code>x++</code>) として用いると、被演算子に 1 を加える前にその値を返します。</td> + <td><code>x</code> が 3 の場合、<code>++x</code> は <code>x</code> に 4 を設定して 4 を返します。一方、<code>x++</code> は 3 を返したあと <code>x</code> に 4 を設定します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Decrement">デクリメント</a> (<code>--</code>)</td> + <td>単項演算子です。被演算子から 1 を引きます。戻り値はインクリメント演算子のものと同様です。</td> + <td><code>x</code> が 3 の場合、<code>--x</code> は <code>x</code> に 2 を設定して 2 を返します。一方、<code>x--</code> は 3 を返したあと <code>x</code> に 2 を設定します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_negation">単項符号反転</a> (<code>-</code>)</td> + <td>単項演算子です。被演算子の符号を反転して、その値を返します。</td> + <td><code>x</code> が 3 のとき、<code>-x</code> は -3 を返します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus">単項プラス</a> (<code>+</code>)</td> + <td>単項演算子です。数値でない被演算子の数値への変換を試みます。</td> + <td><code>+"3"</code> は <code>3</code> を返します。<br> + <code>+true</code> は <code>1</code> を返します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation">べき乗演算子</a> (<code>**</code>) {{experimental_inline}}</td> + <td><code>基数部</code>を<code>指数部</code>乗したものを計算します、つまり、<code>基数部<sup>指数部</sup></code> となります。</td> + <td><code>2 ** 3</code> は <code>8</code> を返します。<br> + <code>10 ** -1</code> は <code>0.1</code> を返します。</td> + </tr> + </tbody> +</table> + +<h3 id="Bitwise_operators" name="Bitwise_operators">ビット演算子</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">ビット演算子</a>はその被演算子を 10進数や 16進数や 8進数ではなく、32 個のビットの集合(0 と 1)として扱います。例えば、10進数の 9 の 2進表現は 1001 です。ビット演算子はこのように 2進表現にした上で演算を行いますが、JavaScript において標準的な 10進数表現の数値を返します。</p> + +<p>次の表は JavaScript のビット演算子の概要です。</p> + +<table class="standard-table"> + <caption>ビット演算子</caption> + <thead> + <tr> + <th scope="col">演算子</th> + <th scope="col" style="width: 5em;">使用法</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_AND">ビット論理積</a> (AND)</td> + <td><code>a & b</code></td> + <td>被演算子の対応するビットがともに 1 である各ビットについて 1 を返します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_OR">ビット論理和</a> (OR)</td> + <td><code>a | b</code></td> + <td>被演算子の対応するビットがともに 0 である各ビットについて 0 を返します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR">ビット排他的論理和</a> (XOR)</td> + <td><code>a ^ b</code></td> + <td>被演算子の対応するビットが同じ各ビットについて 0 を返します。<br> + [被演算子の対応するビットが異なる各ビットについて 1 を返します。]</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT">ビット否定</a> (NOT)</td> + <td><code>~ a</code></td> + <td>被演算子の各ビットを反転します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Left_shift">左シフト</a></td> + <td><code>a << b</code></td> + <td> + <p>2進表現の <code>a</code> を <code>b</code> ビット分だけ左にシフトします。右から 0 で詰めます。</p> + </td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Right_shift">符号維持右シフト</a></td> + <td><code>a >> b</code></td> + <td>2進表現の <code>a</code> を <code>b</code> ビット分だけ右にシフトします。溢れたビットは破棄します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Unsigned_right_shift">ゼロ埋め右シフト</a></td> + <td><code>a >>> b</code></td> + <td>2進表現の <code>a</code> を <code>b</code> ビット分だけ右にシフトします。溢れたビットは破棄し、左から 0 で詰めます。</td> + </tr> + </tbody> +</table> + +<h4 id="Bitwise_Logical_Operators" name="Bitwise_Logical_Operators">ビット論理演算子</h4> + +<p>概念上、ビット論理演算子は以下のように機能します。</p> + +<ul> + <li>被演算子の値は 32 ビットの整数に変換され、0 もしくは 1 からなるビット列として表現されます。32 ビットを超える数値は、32 ビットを超えた部分が捨てられます。次の例では、32 ビットを超える整数が、32 ビットの整数に変換されています。 +<pre class="notranslate">変換前: 1110<code> </code>0110<code> </code>1111<code> </code>1010<code> </code>0000<code> </code>0000<code> </code>0000<code> </code>0110<code> </code>0000<code> </code>0000<code> </code>0001 +変換後: 1010<code> </code>0000<code> </code>0000<code> </code>0000<code> </code>0110<code> </code>0000<code> </code>0000<code> </code>0001</pre> + </li> + <li>第1被演算子の各ビットは第2被演算子の対応する各ビットと対になります。第1 ビットと第1 ビット、第2 ビットと第2 ビット、以下同様に。</li> + <li>演算子は各ビットのペアに適用され、結果はビットごとに構成されます。</li> +</ul> + +<p>例えば 9 の 2進表現は 1001 で、15 の 2進表現は 1111 です。したがって、ビット演算子がこれらの値に適用されたときの結果は以下のようになります。</p> + +<table class="standard-table"> + <caption>ビット演算子の例</caption> + <thead> + <tr> + <th scope="col">演算式</th> + <th scope="col">結果</th> + <th scope="col">2進数での説明</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>15 & 9</code></td> + <td><code>9</code></td> + <td><code>1111 & 1001 = 1001</code></td> + </tr> + <tr> + <td><code>15 | 9</code></td> + <td><code>15</code></td> + <td><code>1111 | 1001 = 1111</code></td> + </tr> + <tr> + <td><code>15 ^ 9</code></td> + <td><code>6</code></td> + <td><code>1111 ^ 1001 = 0110</code></td> + </tr> + <tr> + <td><code>~15</code></td> + <td><code>-16</code></td> + <td><code>~</code><code>00000000...</code><code>00001111 = </code><code>1111</code><code>1111</code><code>...</code><code>11110000</code></td> + </tr> + <tr> + <td><code>~9</code></td> + <td><code>-10</code></td> + <td><code>~</code><code>00000000</code><code>...</code><code>0000</code><code>1001 = </code><code>1111</code><code>1111</code><code>...</code><code>1111</code><code>0110</code></td> + </tr> + </tbody> +</table> + +<p>ビット否定演算子を使うと 32 ビットすべてが反転し、その値の最上位(最左)ビットは負数を表す 1 に設定される(2 の補数表現)ことに注意してください。<code>~x</code> は <code>-x - 1</code> と同じ値に評価されます。</p> + +<h4 id="Bitwise_Shift_Operators" name="Bitwise_Shift_Operators">ビットシフト演算子</h4> + +<p>ビットシフト演算子は 2 つの被演算子をとります。第1被演算子はシフトされる数を指定し、第2被演算子は、第1被演算子をシフトさせるビット数を指定します。シフト演算の方向は使用する演算子によって決まります。</p> + +<p>シフト演算子はその被演算子を 32 ビット整数に変換し、左の被演算子と同じ型で結果を返します。</p> + +<p>シフト演算子の種類は次表のとおりです。</p> + +<table class="fullwidth-table"> + <caption>ビットシフト演算子</caption> + <thead> + <tr> + <th scope="col" style="width: 9em;">演算子</th> + <th scope="col">説明</th> + <th scope="col">例</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#<<_(Left_shift)">左シフト</a><br> + (<code><<</code>)</td> + <td>この演算子は、第1被演算子を指定したビット数分だけ左にシフトします。左に溢れたビットは破棄されます。0 のビットを右から詰めます。</td> + <td><code>9<<2</code> の結果は 36 になります。1001 を 2 ビット左にシフトすると 100100 になり、これは 36 となるからです。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#>>_(Sign-propagating_right_shift)">符号維持右シフト</a> (<code>>></code>)</td> + <td>この演算子は、第1被演算子を指定したビット数分だけ右にシフトします。右に溢れたビットは破棄されます。左端のビットのコピーを左から詰めます。</td> + <td><code>9>>2</code> の結果は 2 になります。1001 を 2 ビット右にシフトすると 10 であり、これは 2 となるからです。同様に、<code>-9>>2</code> の結果は、符号が維持されるため -3 になります。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#>>>_(Zero-fill_right_shift)">ゼロ埋め右シフト (<code>>>></code>)</a></td> + <td>この演算子は、第1被演算子を指定したビット数分だけ右にシフトします。右に溢れたビットは破棄されます。0 のビットを左から詰めます。</td> + <td><code>19>>>2</code> の結果は 4 になります。10011 を 2 ビット右にシフトすると 100 になり、これは 4 となるからです。非負数では、0 埋め右シフトと符号を維持した右シフトは同じ結果になります。</td> + </tr> + </tbody> +</table> + +<h3 id="Logical_operators" name="Logical_operators">論理演算子</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators">論理演算子</a>では、基本的に{{原語併記("ブール値","Boolean value")}}(論理)値を用います。つまりブール値を取ると、ブール値を返します。しかし <code>&&</code> および <code>||</code> 演算子については、実際には指定された被演算子の一方の値を返します。そのため、非ブール値とともに論理演算子が使われた場合、非ブール値を返す可能性があります。次表で論理演算子について説明します。</p> + +<table class="fullwidth-table"> + <caption>論理演算子</caption> + <thead> + <tr> + <th scope="col" style="width: 8em;">演算子</th> + <th scope="col" style="width: 10em;">使用法</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_AND">論理積 (AND)</a> (<code>&&</code>)</td> + <td><code>expr1 && expr2</code></td> + <td><code>expr1</code> を false と見ることができる場合は、<code>expr1</code> を返します。そうでない場合は <code>expr2</code> を返します。したがってブール値を用いた場合、両被演算子が true であれば <code>&&</code> は true を返し、そうでなければ false を返します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR">論理和 (OR)</a> (<code>||</code>)</td> + <td><code>expr1 || expr2</code></td> + <td><code>expr1</code> を true と見ることができる場合は、<code>expr1</code> を返します。そうでない場合は <code>expr2</code> を返します。したがってブール値を用いた場合、どちらかの被演算子が true であれば <code>||</code> は true を返し、両方とも false であれば false を返します。</td> + </tr> + <tr> + <td><a href="/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT">論理否定 (NOT)</a> (<code>!</code>)</td> + <td><code>!expr</code></td> + <td>単一の被演算子を true と見ることができる場合は、false を返します。そうでない場合は true を返します。</td> + </tr> + </tbody> +</table> + +<p>false に変換される式としては、null、0、NaN、空文字列 ("")、undefined に評価される式が挙げられます。</p> + +<p>以下のコードで <code>&&</code> (論理 AND) 演算子の例を示します。</p> + +<pre class="brush: js notranslate">var a1 = true && true; // t && t は true を返す +var a2 = true && false; // t && f は false を返す +var a3 = false && true; // f && t は false を返す +var a4 = false && (3 == 4); // f && f は false を返す +var a5 = 'Cat' && 'Dog'; // t && t は Dog を返す +var a6 = false && 'Cat'; // f && t は false を返す +var a7 = 'Cat' && false; // t && f は false を返す +</pre> + +<p>以下のコードで || (論理 OR) 演算子の例を示します。</p> + +<pre class="brush: js notranslate">var o1 = true || true; // t || t は true を返す +var o2 = false || true; // f || t は true を返す +var o3 = true || false; // t || f は true を返す +var o4 = false || (3 == 4); // f || f は false を返す +var o5 = 'Cat' || 'Dog'; // t || t は Cat を返す +var o6 = false || 'Cat'; // f || t は Cat を返す +var o7 = 'Cat' || false; // t || f は Cat を返す +</pre> + +<p>以下のコードで !(論理 NOT) 演算子の例を示します。</p> + +<pre class="brush: js notranslate">var n1 = !true; // !t は false を返す +var n2 = !false; // !f は true を返す +var n3 = !'Cat'; // !t は false を返す +</pre> + +<h4 id="Short-Circuit_Evaluation" name="Short-Circuit_Evaluation">短絡評価</h4> + +<p>論理式は左から右に評価されるため、以下のルールを用いた「{{原語併記("短絡","short-circuit")}}」評価によるテストが実行できます。</p> + +<ul> + <li><code>false</code> && <em>anything</em> は false へと短絡評価されます。</li> + <li><code>true</code> || <em>anything</em> は true へと短絡評価されます。</li> +</ul> + +<p>論理的なルールにより、これらの評価が常に正確であることが保証されます。上記の式で <em>anything</em> の部分は評価されないため、どのようにしても副作用が生じないことに注意してください。</p> + +<p>2 番目のケースでは、最新のコードで <code>||</code> のように機能する新しい <a href="/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">Null 合体演算子</a> (<code>??</code>) を使用できますが、最初の式が "<a href="/ja/docs/Glossary/Nullish">nullish</a>"、つまり <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a> または <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/undefined"><code>undefined</code></a> の場合にのみ 2 番目の式を返すことに注意してください。したがって、<code>''</code> や <code>0</code> などの値が最初の式の有効な値である場合は、デフォルトを提供することをお勧めします。</p> + +<h3 id="String_operators" name="String_operators">文字列演算子</h3> + +<p>文字列に対して使用することができる演算子には、比較演算子に加えて、2 つの文字列を結合する結合演算子 (+) があり、2 つの被演算子の文字列を結合した文字列を返します。</p> + +<p>例えば、</p> + +<pre class="brush: js notranslate">console.log('my ' + 'string'); // 文字列 "my string" がログに表示される。</pre> + +<p>短縮表記した代入演算子 += も文字列の結合に使用できます。</p> + +<p>例えば、</p> + +<pre class="brush: js notranslate">var mystring = 'alpha'; +mystring += 'bet'; // "alphabet" と評価されて、mystring にその値を代入します。</pre> + +<h3 id="Conditional_ternary_operator" name="Conditional_(ternary)_operator">条件(三項)演算子</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">条件演算子</a>は JavaScript で唯一 3 つの被演算子を取る演算子です。条件に基づいて 2 つの値のうち 1 つを選択します。構文は以下の通りです。</p> + +<pre class="syntaxbox notranslate"><em>条件</em> ? <em>値1</em> : <em>値2</em> +</pre> + +<p><code>条件</code>が真の場合、演算子は<code>値1</code> の値を選択します。そうでない場合、<code>値2</code> の値を選択します。標準的な演算子を使用できる場所ならどこでも条件演算子を使用できます。</p> + +<p>例えば、</p> + +<pre class="brush: js notranslate">var status = (age >= 18) ? 'adult' : 'minor'; +</pre> + +<p>この文では、<code>age</code> が 18 以上の場合、変数 <code>status</code> に "adult" の値が代入されます。そうでない場合 <code>status</code> には "minor" が代入されます。</p> + +<h3 id="Comma_operator" name="Comma_operator">カンマ演算子</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Comma_Operator">カンマ演算子</a> (<code>,</code>) は両側の被演算子を単純に評価し、最後の被演算子の値を返します。この演算子は主に <code>for</code> ループ内で使用され、これによりループのたびに複数の変数を更新できます。</p> + +<p>例えば、一辺が 10 要素の 2 次元配列 <code>a</code> があったとして、以下のコードでカンマ演算子を用いて 2 つの変数を同時にインクリメントしています。このコードでは配列の対角成分の値を出力します。</p> + +<pre class="brush: js notranslate">var x = [0,1,2,3,4,5,6,7,8,9] +var a = [x, x, x, x, x]; + +for (var i = 0, j = 9; i <= j; i++, j--) +// ^ + console.log('a[' + i + '][' + j + ']= ' + a[i][j]); +</pre> + +<h3 id="Unary_operators" name="Unary_operators">単項演算子</h3> + +<p>単項演算は被演算子を 1 つだけ取る演算です。</p> + +<h4 id="delete" name="delete"><code>delete</code></h4> + +<p><code><a href="/ja/docs/Web/JavaScript/Reference/Operators/delete">delete</a></code> 演算子はオブジェクトやオブジェクトのプロパティ、配列の指定されたインデックスの要素を削除します。構文は以下のとおりです。</p> + +<pre class="brush: js notranslate">delete object.property; +delete object[propertyKey]; +delete objectName[index]; +delete property; // legal only within a with statement +</pre> + +<p>ここで <code>object</code> はオブジェクトの名前を、<code>property</code> は既存のプロパティを、<code>propertyKey</code> は配列の要素の位置を示す整数をそれぞれ表しています。</p> + +<p>4番目の形式は <code><a href="/ja/docs/Web/JavaScript/Reference/Statements/with">with</a></code> 文内でのみ有効で、これはあるオブジェクトからプロパティを削除します。</p> + +<p><code>delete</code> を用いて暗黙的に宣言された変数を削除できますが、<code>var</code> 文で宣言された変数は削除できません。</p> + +<p><code>delete</code> 演算が成功すると、そのプロパティや要素には <code>undefined</code> がセットされます。また、演算が可能だった場合に <code>delete</code> 演算子は <code>true</code> を返します。演算が不可能である場合は <code>false</code> を返します。</p> + +<pre class="brush: js notranslate">x = 42; // 暗黙のうちに window.x を作成 +var y = 43; +var myobj = {h: 4}; // プロパティ h を持つオブジェクトを作成 + +delete x; // false を返す (暗黙的に作成された場合は削除不可能) +delete y; // false を返す (var つきで宣言された場合は削除不可能) +delete Math.PI; // false を返す (定義済みプロパティは削除不可能) +delete myobj.h; // true を返す (ユーザー定義プロパティは削除可能) +</pre> + +<h5 id="Deleting_array_elements" name="Deleting_array_elements">配列要素の削除</h5> + +<p>配列は単なるオブジェクトの集まりであるため、技術的には各要素を削除することが可能です。しかしそれは悪しき慣例とみなされており、使用しないでください。配列の要素を削除したとき、配列の長さは影響を受けず、他の要素は再インデックスされません。この振る舞いを達成するのであれば、単に要素を <code>undefined</code> で上書きするほうがはるかに良い方法です。実際に配列を操作するためには、<code><a href="https://wiki.developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">splice</a></code> のようなさまざまな配列のメソッドを使用してください。</p> + +<h4 id="typeof" name="typeof"><code>typeof</code></h4> + +<p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/typeof"><code>typeof</code> 演算子</a>は次の方法のうち、どちらかの方法で使用します。</p> + +<pre class="syntaxbox notranslate">typeof 被演算子 +typeof (被演算子) +</pre> + +<p><code>typeof</code> 演算子は、未評価の被演算子の型を指す文字列を返します。<code>被演算子</code>には返される型を調べる対象となる文字列、キーワード、オブジェクトを指定します。括弧はあってもなくてもかまいません。</p> + +<p>以下の変数を定義することにしましょう。</p> + +<pre class="brush: js notranslate">var myFun = new Function('5 + 2'); +var shape = 'round'; +var size = 1; +var foo = ['Apple', 'Mango', 'Orange']; +var today = new Date(); +</pre> + +<p><code>typeof</code> 演算子は、変数の型に応じて以下の値を返します。</p> + +<pre class="brush: js notranslate">typeof myFun; // "function" を返す +typeof shape; // "string" を返す +typeof size; // "number" を返す +typeof foo; // "object" を返す +typeof today; // "object" を返す +typeof doesntExist; // "undefined" を返す +</pre> + +<p><code>true</code> や <code>null</code> というキーワードに対して、<code>typeof</code> 演算子は以下の結果を返します。</p> + +<pre class="brush: js notranslate">typeof true; // "boolean" を返す +typeof null; // "object" を返す +</pre> + +<p>数値や文字列に対して、<code>typeof</code> 演算子は以下の結果を返します。</p> + +<pre class="brush: js notranslate">typeof 62; // "number" を返す +typeof 'Hello world'; // "string" を返す +</pre> + +<p>プロパティ値に対して、<code>typeof</code> 演算子はプロパティが持つ値の型を返します。</p> + +<pre class="brush: js notranslate">typeof document.lastModified; // "string" を返す +typeof window.length; // "number" を返す +typeof Math.LN2; // "number" を返す +</pre> + +<p>メソッドや関数に対して、<code>typeof</code> 演算子は以下の結果を返します。</p> + +<pre class="brush: js notranslate">typeof blur; // "function" を返す +typeof eval; // "function" を返す +typeof parseInt; // "function" を返す +typeof shape.split; // "function" を返す +</pre> + +<p>定義済みオブジェクトに対して、<code>typeof</code> 演算子は以下の結果を返します。</p> + +<pre class="brush: js notranslate">typeof Date; // "function" を返す +typeof Function; // "function" を返す +typeof Math; // "object" を返す +typeof Option; // "function" を返す +typeof String; // "function" を返す +</pre> + +<h4 id="void" name="void"><code>void</code></h4> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/void"><code>void</code> 演算子</a>は以下のどちらかの方法で使用します。</p> + +<pre class="syntaxbox notranslate">void (式) +void 式 +</pre> + +<p><code>void</code> 演算子は、値を返さずに評価する式を指定します。<code>式</code>は評価する JavaScript の式となります。式の周りの括弧はあってもなくてもかまいませんが、使用する方が見た目がよいです。</p> + +<h3 id="Relational_operators" name="Relational_operators">関係演算子</h3> + +<p>関係演算子は被演算子を比較し、比較結果が真かどうかに基づいて <code>Boolean</code> の値を返します。</p> + +<h4 id="in" name="in"><code>in</code></h4> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/in"><code>in</code> 演算子</a>は、指定したプロパティが指定のオブジェクトにある場合に <code>true</code> を返します。構文は以下のとおりです。</p> + +<pre class="syntaxbox notranslate">プロパティ名または数値 in オブジェクト名 +</pre> + +<p>ここで <code>プロパティ名または数値</code>はプロパティ名または配列のインデックスを表す文字列、数値または記号式を、<code>オブジェクト名</code>はオブジェクトの名前をそれぞれ表します。</p> + +<p>次の例で <code>in</code> 演算子の使用法を示します。</p> + +<pre class="brush:js notranslate">// 配列 +var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; +0 in trees; // true を返す +3 in trees; // true を返す +6 in trees; // false を返す +'bay' in trees; // false を返す(インデックスの指す値ではなく、 + // インデックスの数字を指定しなければならない) +'length' in trees; // true を返す(length は Array のプロパティ) + +// 定義済みオブジェクト +'PI' in Math; // true を返す +var myString = new String('coral'); +'length' in myString; // true を返す + +// ユーザー定義オブジェクト +var mycar = { make: 'Honda', model: 'Accord', year: 1998 }; +'make' in mycar; // returns true +'model' in mycar; // returns true +</pre> + +<h4 id="instanceof" name="instanceof"><code>instanceof</code></h4> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/instanceof"><code>instanceof</code> 演算子</a>は、指定されたオブジェクトが指定されたオブジェクトの種類である場合に <code>true</code> を返します。構文は以下のとおりです。</p> + +<pre class="syntaxbox notranslate">オブジェクト名 instanceof オブジェクト型 +</pre> + +<p>ここで<code>オブジェクト名</code>は<code>オブジェクト型</code>と比較するオブジェクトの名前を、<code>オブジェクト型</code>は {{jsxref("Date")}} や {{jsxref("Array")}} のようなオブジェクトの種類をそれぞれ表します。</p> + +<p>実行時にオブジェクトの種類を確認する必要があるときは <code>instanceof</code> を使用してください。例えば例外を受け取るとき、発生した例外の種類に応じて、別々の例外を扱うコードに分岐することができます。</p> + +<p>例えば次のコードでは、<code>instanceof</code> を使用して <code>theDay</code> が <code>Date</code> オブジェクトであるかを判断しています。<code>theDay</code> は <code>Date</code> オブジェクトであるため、<code>if</code> 文中の文が実行されます。</p> + +<pre class="brush: js notranslate">var theDay = new Date(1995, 12, 17); +if (theDay instanceof Date) { + // 実行する文 +} +</pre> + +<h3 id="Operator_precedence" name="Operator_precedence">演算子の優先順位</h3> + +<p>演算子の<em>優先順位</em>によって、式評価の際に演算子が適用される順番が定義されています。括弧を用いることで演算子の優先順位を上書きすることができます。</p> + +<p>次の表では演算子の優先順位を、高いものから低い順に並べています。</p> + +<table class="standard-table"> + <caption>演算子の優先順位</caption> + <thead> + <tr> + <th scope="col">演算子の種類</th> + <th scope="col">対応する演算子</th> + </tr> + </thead> + <tbody> + <tr> + <td>メンバー</td> + <td><code>. []</code></td> + </tr> + <tr> + <td>インスタンスの呼び出し/作成</td> + <td><code>() new</code></td> + </tr> + <tr> + <td>否定/インクリメント</td> + <td><code>! ~ - + ++ -- typeof void delete</code></td> + </tr> + <tr> + <td>乗算/除算</td> + <td><code>* / %</code></td> + </tr> + <tr> + <td>加算/減算</td> + <td><code>+ -</code></td> + </tr> + <tr> + <td>ビットシフト</td> + <td><code><< >> >>></code></td> + </tr> + <tr> + <td>関係</td> + <td><code>< <= > >= in instanceof</code></td> + </tr> + <tr> + <td>等値</td> + <td><code>== != === !==</code></td> + </tr> + <tr> + <td>ビット論理積</td> + <td><code>&</code></td> + </tr> + <tr> + <td>ビット排他的論理和</td> + <td><code>^</code></td> + </tr> + <tr> + <td>ビット論理和</td> + <td><code>|</code></td> + </tr> + <tr> + <td>論理積</td> + <td><code>&&</code></td> + </tr> + <tr> + <td>論理和</td> + <td><code>||</code></td> + </tr> + <tr> + <td>条件</td> + <td><code>?:</code></td> + </tr> + <tr> + <td>代入</td> + <td><code>= += -= *= /= %= <<= >>= >>>= &= ^= |= &&= ||= ??= </code></td> + </tr> + <tr> + <td>カンマ</td> + <td><code>,</code></td> + </tr> + </tbody> +</table> + +<p>それぞれの演算子についてのリンクを含むこの表の詳細版に関しては <a href="/ja/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table">JavaScript リファレンス</a>を参照してください。</p> + +<h2 id="Expressions" name="Expressions">式</h2> + +<p><em>式</em>とは、ある値へと決定される有効なコードの単位のことです。</p> + +<p>文法的に正しい式は必ず何らかの値に決定されますが、概念的に、副作用の有無によって 2種類にわけられます。代入演算は副作用のあるものの代表です。副作用の無いものは、式そのものが評価されその値が決定されます。</p> + +<p><code>x = 7</code> という式が前者の例です。この式では <code>x</code> に 7 という値を代入するのに = <em>演算子</em>を使っています。この式自体は 7 と評価されます。</p> + +<p><code>3 + 4</code> という式は後者の例です。この式では 3 と 4 を加算するのに + 演算子を使っており、計算結果の 7 を変数に代入していません。<br> + <br> + JavaScript には、以下の種類の式があります。</p> + +<ul> + <li>算術式 : 評価結果は数値になります。例えば 3.14159 など。(一般に<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#Arithmetic_operators">算術演算子</a>を使用します)</li> + <li>文字列式 : 評価結果は文字列になります。例えば "Fred" や "234" など。(一般に<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#String_operators">文字列演算子</a>を使用します)</li> + <li>論理式 : 評価結果は true または false になります。(よく<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical_operators">論理演算子</a>を用います)</li> + <li>基本式 : JavaScript にある基本のキーワードと一般的な式です。</li> + <li>左辺式 : 代入先になるような式です。</li> +</ul> + +<h3 id="Primary_expressions" name="Primary_expressions">基本式</h3> + +<p>JavaScript における基本のキーワードと一般的な式です。</p> + +<h4 id="this" name="this"><code>this</code></h4> + +<p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/this"><code>this</code> キーワード</a>を使用することで現在のオブジェクトを参照できます。一般的に <code>this</code> は、あるメソッド内で呼び出されるオブジェクトを参照します。<code>this</code> の使用法は以下のとおりです。</p> + +<pre class="syntaxbox notranslate">this['propertyName'] +this.propertyName +</pre> + +<p>オブジェクトと上限および下限の値を渡し、そのオブジェクトの <code>value</code> プロパティを検証する <code>validate</code> という関数があるとしましょう。</p> + +<pre class="brush: js notranslate">function validate(obj, lowval, hival) { + if ((obj.value < lowval) || (obj.value > hival)) + console.log('Invalid Value!'); +} +</pre> + +<p>次の例のように、各フォーム要素の <code>onChange</code> イベントハンドラにおいて <code>validate</code> を呼び出し、その関数にフォーム要素を渡すのに <code>this</code> を使うことができます。</p> + +<pre class="brush: html notranslate"><p>Enter a number between 18 and 99:</p> +<input type="text" name="age" size=3 onChange="validate(this, 18, 99);"> +</pre> + +<h4 id="Grouping_operator" name="Grouping_operator">グループ化演算子</h4> + +<p>グループ化演算子 <code>( )</code> は式内での評価の優先順位を制御します。例えば、加算が最初に評価されるよう、最初に行われる演算を乗算と除算から加算と減算へと上書きすることができます。</p> + +<pre class="brush:js notranslate">var a = 1; +var b = 2; +var c = 3; + +// デフォルトの優先順位 +a + b * c // 7 +// デフォルトではこのように評価される +a + (b * c) // 7 + +// 優先順位を上書きし、 +// 乗算の前に加算を行う +(a + b) * c // 9 + +// この式と同等となる +a * c + b * c // 9 +</pre> + +<h3 id="Left-hand-side_expressions" name="Left-hand-side_expressions">左辺式</h3> + +<p>左辺値は、代入する宛先です。</p> + +<h4 id="new" name="new"><code>new</code></h4> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/new"><code>new</code> 演算子</a>は、ユーザー定義オブジェクトやビルトインオブジェクトのインスタンス作成に使用します。<code>new</code> の使用法は以下のとおりです。</p> + +<pre class="brush: js notranslate">var オブジェクト名 = new objectType([引数1, 引数2, ..., 引数N]); +</pre> + +<h4 id="super" name="super">super</h4> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/super">super キーワード</a>は自分の親のオブジェクトに関数を呼び出すのに使います。これは下の例のように、<a href="/ja/docs/Web/JavaScript/Reference/Classes">クラス</a>と共に使って親のコンストラクタを呼び出すのに便利です。</p> + +<pre class="syntaxbox notranslate">super([引数]); // 親のコンストラクタを呼び出す。 +super.親の関数([引数]); +</pre> + +<div>{{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}}</div> diff --git a/files/ja/web/javascript/guide/functions/index.html b/files/ja/web/javascript/guide/functions/index.html new file mode 100644 index 0000000000..c519b43ae3 --- /dev/null +++ b/files/ja/web/javascript/guide/functions/index.html @@ -0,0 +1,696 @@ +--- +title: 関数 +slug: Web/JavaScript/Guide/Functions +tags: + - Beginner + - Functions + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Functions +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}</div> + +<p class="summary">関数は JavaScript の基本的な構成要素のひとつです。また関数は、JavaScript の手続き ― つまり、タスクや値計算を実行する文の集まりです。関数を使うには、呼び出したいスコープ内のどこかでそれを定義する必要があります。</p> + +<p>より詳しくは <a href="/ja/docs/Web/JavaScript/Reference/Functions">JavaScript の関数に関する完全なリファレンスについての章</a>をご覧ください。</p> + +<h2 id="Defining_functions" name="Defining_functions">関数を定義する</h2> + +<h3 id="Function_declarations" name="Function_declarations">関数の宣言</h3> + +<p><strong>関数の定義</strong>(<strong>関数の宣言</strong>や{{原語併記("<strong>関数定義文</strong>","function statement")}} とも呼ばれます)は <code><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function" title="function">function</a></code> キーワードと、それに続く以下の内容で構成されます。</p> + +<ul> + <li>関数の名前。</li> + <li>関数への引数のリスト。丸括弧でくくり、カンマで区切ります。</li> + <li>関数を定義する JavaScript の文。波括弧 <code>{ }</code> でくくります。</li> +</ul> + +<p>例えば、次のコードは <code>square</code> という名前の簡単な関数を定義します :</p> + +<pre class="brush: js notranslate">function square(number) { + return number * number; +} +</pre> + +<p>関数 <code>square</code> は <code>number</code> という名前の引数を 1 つとります。この関数は、引数(すなわち <code>number</code>)の 2 乗を返すように指示する 1 つの文で構成されています。<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/return" title="return"><code>return</code></a> 文は、関数が返す値を指定します。</p> + +<pre class="brush: js notranslate">return number * number; +</pre> + +<p>プリミティブなパラメータ(数値など)は<strong>値渡し</strong>で関数に渡されます。つまり、値は関数に渡されますが、関数がパラメータの値を変更しても、<strong>この変更はグローバルな値や関数の呼び出し元の値には影響を与えません</strong>。</p> + +<p>オブジェクト(すなわち非プリミティブ値、例えば {{jsxref("Array")}} オブジェクトやユーザー定義オブジェクトなど)をパラメータとして渡すと、関数がオブジェクトのプロパティを変更した場合、その変更が関数外でも有効になります。次の例をご覧ください :</p> + +<pre class="brush: js notranslate">function myFunc(theObject) { + theObject.make = 'Toyota'; +} + +var mycar = {make: 'Honda', model: 'Accord', year: 1998}; +var x, y; + +x = mycar.make; // x は "Honda" という値になる + +myFunc(mycar); +y = mycar.make; // y は "Toyota" という値になる + //(プロパティが関数で変更されている) +</pre> + +<h3 id="Function_expressions" name="Function_expressions">関数式</h3> + +<p>ここまでの関数宣言はすべて構文的な文でしたが、関数は<strong>関数式</strong>によって作成することもできます。このような関数は<strong>{{原語併記("無名","anonymous")}}</strong> にできます。名前をつけなくてもよいのです。例えば、関数 <code>square</code> は次のように定義できます :</p> + +<pre class="brush: js notranslate">const square = function(number) { return number * number } +var x = square(4) // x の値は 16 となる</pre> + +<p>ただし関数式は名前をつけることもでき、関数内で自身を参照することや、デバッガーのスタックトレースで関数を特定することに利用できます:</p> + +<pre class="brush: js notranslate">const factorial = function fac(n) { return n < 2 ? 1 : n * fac(n - 1) } + +console.log(factorial(3)) +</pre> + +<p>関数式は、ある関数を別の関数の引数として渡すときに便利です。次の例では <code>map</code> 関数を定義し、第 1 引数に関数を取り、第 2 引数に配列を取ります:</p> + +<pre class="brush: js notranslate">function map(f, a) { + let result = []; // 新しい配列を作成 + let i; // 変数の宣言 + for (i = 0; i != a.length; i++) + result[i] = f(a[i]); + return result; +} +</pre> + +<p>下記のコードでは、この関数は関数式で定義された関数を受け取って、2 つ目の引数で受け取った配列の各要素に対して実行しています。</p> + +<pre class="brush: js notranslate">function map(f, a) { + let result = []; // 新しい配列を作成 + let i; // 変数の宣言 + for (i = 0; i != a.length; i++) + result[i] = f(a[i]); + return result; +} +var f = function(x) { + return x * x * x; +} +let numbers = [0, 1, 2, 5, 10]; +let cube = map(f,numbers); +console.log(cube);</pre> + +<p>これは [0, 1, 8, 125, 1000] を返します。</p> + +<p>JavaScript では、条件に基づいて関数を定義することもできます。例えば次の関数の定義は、変数 <code>num</code> が 0 に等しい場合のみ <code>myFunc</code> という関数を定義します :</p> + +<pre class="brush: js notranslate">var myFunc; +if (num === 0) { + myFunc = function(theObject) { + theObject.make = 'Toyota'; + } +}</pre> + +<p>これまで説明してきた関数の定義に加えて、{{jsxref("Function")}} コンストラクタを、{{jsxref( "eval", "eval()")}} のように文字列からの関数作成に用いることができます。</p> + +<p><strong>メソッド</strong>は、オブジェクトのプロパティである関数のことです。オブジェクトとメソッドについて詳しくは、「<a href="/ja/docs/JavaScript/Guide/Working_with_Objects">オブジェクトを利用する</a>」の章をご覧ください。</p> + +<h2 id="Calling_functions" name="Calling_functions">関数を呼び出す</h2> + +<p>関数を定義しても、その関数が実行されるわけではありません。関数の定義とは、ただ単に関数に名前をつけ、その関数が呼び出されたときに何をするかを指定することです。関数の<strong>呼び出し</strong>は、実際に指定したパラメータを用いて指定された動作を実行するということです。例えば、関数 <code>square</code> を定義した場合、次のようにしてそれを呼び出すことができます:</p> + +<pre class="brush: js notranslate">square(5); +</pre> + +<p>この文は 5 という引数とともに関数を呼び出します。関数は自身の文を実行し、25 という値を返します。</p> + +<p>関数は呼び出されるスコープ内になければいけませんが、次の例のように、関数の宣言は呼び出しより後に置くことができます :</p> + +<pre class="brush: js notranslate">console.log(square(5)); +/* ... */ +function square(n) { return n * n } +</pre> + +<p>関数のスコープは自身が宣言された関数内、あるいはトップレベルで宣言されたのであればプログラム全体になります。</p> + +<div class="note"> +<p><strong>注:</strong> この動作は、上記の構文(すなわち <code>function funcName(){}</code>)を用いて関数を定義したときに限ることに注意してください。次のコードは動作しません。</p> + +<p>これは、関数の巻き上げが<em>関数式</em>ではなく<em>関数宣言</em>でしか機能しないことを意味しています。</p> + +<pre class="brush: js example-bad notranslate">console.log(square) // square は初期値が undefined の状態で巻き上げられています。 +console.log(square(5)) // Uncaught TypeError: square is not a function +const square = function(n) { + return n * n; +} +</pre> +</div> + +<p>関数の引数は、文字列や数値に限られてはいません。オブジェクト全体を関数に渡すこともできます。<code>show_props</code> 関数(「<a href="/ja/docs/JavaScript/Guide/Working_with_Objects#Objects_and_Properties">オブジェクトを利用する</a>」の章で定義)は、オブジェクトを引数にとる関数の例です。</p> + +<p>関数はその関数自身を呼び出すこともできます。例えば、ここに階乗を計算する関数を示します:</p> + +<pre class="brush: js notranslate">function factorial(n) { + if ((n === 0) || (n === 1)) + return 1; + else + return (n * factorial(n - 1)); +} +</pre> + +<p>1 から 5 までの階乗の計算は、次のようになります:</p> + +<pre class="brush: js notranslate">var a, b, c, d, e; +a = factorial(1); // a の値は 1 となる +b = factorial(2); // b の値は 2 となる +c = factorial(3); // c の値は 6 となる +d = factorial(4); // d の値は 24 となる +e = factorial(5); // e の値は 120 となる +</pre> + +<p>関数を呼び出す方法は他にもあります。関数を動的に呼び出す、関数の引数の数を変える、関数を呼び出すコンテキストを実行時に決まる特定のオブジェクトにセットするといった場合があります。</p> + +<p>関数は関数であるとともにオブジェクトでもあり、また結果としてそれらのオブジェクトはメソッドを持っています({{jsxref("Function")}} オブジェクトをご覧ください)。そうしたメソッドのひとつ、{{jsxref("Function/apply","apply()")}} メソッドを用いることでこの目的を実現できます。</p> + +<h2 id="Function_scope" name="Function_scope">関数のスコープ</h2> + +<p>関数の内部で宣言された変数は、関数の外部からアクセスすることができません。これは、変数が関数のスコープ内でのみ定義されているためです。その一方、関数は自身が定義されたスコープ内で定義されているすべての変数や関数にアクセスできます。</p> + +<p>言い換えると、グローバルスコープで定義された関数は、グローバルスコープで定義されたすべての変数にアクセスできます。ある関数の内部で宣言された関数は、自身の親となる関数内で定義されたすべての変数や、その関数がアクセス権を持つ他の変数にもアクセスできます。</p> + +<pre class="brush: js notranslate">// 以下の変数はグローバルスコープで定義 +var num1 = 20, + num2 = 3, + name = 'Chamahk'; + +// この関数はグローバルスコープで定義 +function multiply() { + return num1 * num2; +} + +multiply(); // 60 を返す + +// 入れ子になっている関数の例 +function getScore () { + var num1 = 2, + num2 = 3; + + function add() { + return name + ' scored ' + (num1 + num2); + } + + return add(); +} + +getScore(); // "Chamahk scored 5" を返す +</pre> + +<h2 id="Scope_and_the_function_stack" name="Scope_and_the_function_stack">スコープと関数スタック</h2> + +<h3 id="Recursion" name="Recursion">再帰</h3> + +<p>関数は自身を参照し、そして呼び出すことができます。関数が自身を参照する方法は 3 種類あります :</p> + +<ol> + <li>関数名</li> + <li><code><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/arguments/callee">arguments.callee</a></code></li> + <li>関数を参照したスコープ内変数</li> +</ol> + +<p>例えば、以下のような関数定義を考えてみましょう :</p> + +<pre class="brush: js notranslate">var foo = function bar() { + // ここには文が来る +} +</pre> + +<p>関数本体の中で、以下のものはすべて同様の意味となります :</p> + +<ol> + <li><code>bar()</code></li> + <li><code>arguments.callee()</code></li> + <li><code>foo()</code></li> +</ol> + +<p>自身を呼び出す関数のことを<strong>再帰関数</strong>と言います。いくつかの点で、再帰はループに似ています。どちらも同じコードを何度も実行しますし、条件(無限ループを防ぐため、というより無限再帰を防ぐため)が必要です。例えば、以下のループは、:</p> + +<pre class="brush: js notranslate">var x = 0; +while (x < 10) { // "x < 10" がループ条件 + // 何らかの処理を行う + x++; +} +</pre> + +<p>再帰関数とその呼び出しとに置き換えることができます :</p> + +<pre class="brush: js notranslate">function loop(x) { + if (x >= 10) // "x >= 10" が終了条件 ("!(x < 10)" と同等) + return; + // 何らかの処理を行う + loop(x + 1); // 再帰呼出し +} +loop(0); +</pre> + +<p>一方で、単純な反復ループでは行えないアルゴリズムもあります。例えば、ツリー構造のすべてのノード(例えば <a href="/ja/docs/DOM">DOM</a> )を取得するのに、再帰を使うとより簡単に行えます :</p> + +<pre class="brush: js notranslate">function walkTree(node) { + if (node == null) // + return; + // ノードに対し処理を行う + for (var i = 0; i < node.childNodes.length; i++) { + walkTree(node.childNodes[i]); + } +} +</pre> + +<p>関数 <code>loop</code> と比較して、それぞれの再帰呼出しによってさらに多数の再帰呼出しが行われています。</p> + +<p>どんな再帰アルゴリズムも再帰でないものに書き換えることが可能です、しかしロジックはより複雑になり、データをスタックしておく必要がたびたび出てきます。実際、再帰自体がスタックを使用しています。それが関数スタックです。</p> + +<p>以下の例で、スタックとはどういったふるまいをするのか見ることができます :</p> + +<pre class="brush: js notranslate">function foo(i) { + if (i < 0) + return; + console.log('begin: ' + i); + foo(i - 1); + console.log('end: ' + i); +} +foo(3); + +// 出力: + +// begin: 3 +// begin: 2 +// begin: 1 +// begin: 0 +// end: 0 +// end: 1 +// end: 2 +// end: 3</pre> + +<h3 id="Nested_functions_and_closures" name="Nested_functions_and_closures">入れ子の関数とクロージャ</h3> + +<p>関数の中に関数を入れ子に(ネスト)することができます。入れ子になった(内部の)関数は、それを含んでいる(外部の)関数からはプライベートとなります。</p> + +<p>これにより<strong>クロージャ</strong>が作られます。クロージャとは、環境に束縛された(式によって「閉じ込められた」)変数を自由に持たせることができる式(通常は一つの関数)のことです。</p> + +<p>入れ子になった関数はクロージャなので、これはつまり、入れ子になった関数は内包する関数の引数と変数を「継承」することができるということです。別の言い方をすれば、内部の関数は外部の関数のスコープを持っているということです。</p> + +<p>まとめると :</p> + +<ul> + <li>内部の関数へは、外部関数内の文からのみアクセスできます。</li> + <li>内部の関数はクロージャを形作ります。内部関数は外部関数の引数と変数を利用でき、その一方外部関数は内部関数の引数と変数を利用できません。</li> +</ul> + +<p>以下の実例では入れ子になった関数が示されています :</p> + +<pre class="brush: js notranslate">function addSquares(a, b) { + function square(x) { + return x * x; + } + return square(a) + square(b); +} +a = addSquares(2, 3); // 13 を返す +b = addSquares(3, 4); // 25 を返す +c = addSquares(4, 5); // 41 を返す +</pre> + +<p>内部の関数はクロージャとなるので、外部の関数からクロージャを呼び出し、外部と内部両方の関数に対し引数を指定することができます :</p> + +<pre class="brush: js notranslate">function outside(x) { + function inside(y) { + return x + y; + } + return inside; +} +fn_inside = outside(3); // このように考えてください : 与えられたものに 3 を加算する関数を代入します + +result = fn_inside(5); // 8 を返す + +result1 = outside(3)(5); // 8 を返す +</pre> + +<h3 id="Preservation_of_variables" name="Preservation_of_variables">変数の保護</h3> + +<p><code>inside</code> が返されるとき、変数 <code>x</code> がどのように保護されるのかに注目してください。クロージャはそれ自身が参照しているすべてのスコープ内の引数と変数を保護することになります。それぞれの呼び出しには異なる引数が渡される可能性があるので、それぞれの <code>outside</code> の呼び出しに対し新しいクロージャが作られます。返された <code>inside</code> がもはやアクセスできなくなった時にのみメモリーは開放されます。</p> + +<p>これはその他のオブジェクトの内部で参照を保持する場合と違いはないのですが、クロージャの場合は直接参照を設定せず、また情報を取得できないので、明白さは劣ります。</p> + +<h3 id="Multiply-nested_functions" name="Multiply-nested_functions">多重入れ子関数</h3> + +<p>関数は多重に入れ子にすることができます。例えば :</p> + +<ul> + <li>関数 (<code>A</code>) は関数 (<code>B</code>) を含み、関数 (<code>B</code>) は関数 (<code>C</code>) を含んでいます。</li> + <li>ここで、関数 <code>B</code> と <code>C</code> はクロージャとなるので、<code>B</code> は <code>A</code> にアクセスでき、<code>C</code> は <code>B</code> にアクセスできます。</li> + <li>さらに、<code>C</code> は <code>A</code> にアクセスできる <code>B</code> にアクセスできるので、<code>C</code> は <code>A</code> にもアクセスできます。</li> +</ul> + +<p>このようにして、クロージャは多重スコープを導入できます。つまり関数のスコープが再帰的に包含されているのです。これを<em>スコープチェーン</em>と呼びます。(なぜ「チェーン」と呼ぶのかは後で説明します。)</p> + +<p>次の例を見てみましょう :</p> + +<pre class="brush: js notranslate">function A(x) { + function B(y) { + function C(z) { + console.log(x + y + z); + } + C(3); + } + B(2); +} +A(1); // 6 がログに出力される (1 + 2 + 3) +</pre> + +<p>この例では、関数 <code>C</code> は関数 <code>B</code> の引数 <code>y</code> と関数 <code>A</code> の引数 <code>x</code> にアクセスしています。</p> + +<p>なぜこれが可能かというと :</p> + +<ol> + <li>関数 <code>B</code> は関数 <code>A</code> に含まれたクロージャとなっています、言い換えると <code>B</code> は <code>A</code> の引数と変数にアクセスできます。</li> + <li>関数 <code>C</code> は関数 <code>B</code> に含まれたクロージャとなっています。</li> + <li>クロージャ <code>B</code> は <code>A</code> の中にあり、クロージャ <code>C</code> も <code>A</code> の中にあるので、<code>C</code> は <code>B</code>、<strong>そしてさらに</strong> <code>A</code> の引数と変数にアクセスできます。言い換えれば、<code>C</code> は <code>B</code>、<code>A</code> の順でスコープが{{原語併記("つながっている","chain")}} のです。</li> +</ol> + +<p>その一方で、逆は成り立ちません。<code>A</code> は <code>C</code> にアクセスできません、なぜなら <code>A</code> は、<code>C</code> を変数の一つとして持っている <code>B</code> の引数や変数にはアクセスできないからです。このように <code>C</code> は <code>B</code> からのみプライベートとなっています。</p> + +<h3 id="Name_conflicts" name="Name_conflicts">名前衝突</h3> + +<p>クロージャ中のスコープに同じ名前の 2 つの引数や変数がある場合、<strong>名前衝突</strong>が生じます。より内部のスコープが優先されるので、最内部にあるスコープが最優先に、一方最も外側のスコープが最も低い優先度となります。これがスコープチェーンです。チェーンの最初は最内部のスコープ、そして最後は最外部のスコープとなります。次の例を見てみましょう :</p> + +<pre class="brush: js notranslate">function outside() { + var x = 5; + function inside(x) { + return x * 2; + } + return inside; +} + +outside()(10); // 10 ではなく 20 を返す +</pre> + +<p>文 <code>return x</code> の箇所で、<code>inside</code> の引数 <code>x</code> と <code>outside</code> の変数 <code>x</code> との間に名前衝突が起きています。ここでのスコープチェーンは、{ <code>inside</code>, <code>outside</code>, グローバルオブジェクト } です。したがって <code>inside</code> の <code>x</code> が <code>outside</code> の <code>x</code> より優先され、結果 10 (<code>outside</code> の <code>x</code>)ではなく、20 (<code>inside</code> の <code>x</code>)が返されます。</p> + +<h2 id="Closures" name="Closures">クロージャ</h2> + +<p>クロージャは、JavaScript でもっとも強力な機能のひとつです。JavaScript では関数の入れ子が可能であることに加えて、内側の関数が外側の関数内で定義されたすべての変数や関数に対し(外側の関数がアクセスできる、他の変数や関数すべてにも)自由にアクセスできます。</p> + +<p>しかし、外側の関数は内側の関数内で定義された変数や関数にアクセスできません。これは、内側の関数の変数に対する一種のセキュリティ機構を提供します。</p> + +<p>また、内側の関数は外側の関数のスコープにアクセスできることから、もし内側の関数が外側の関数よりも長く生存できた場合、外側の関数内で定義された変数や関数は外側の関数よりも長く残る可能性があります。クロージャは、内側の関数が何かしらの形で外側の関数のスコープ外のどこかで使用可能になった場合に作られます。</p> + +<pre class="brush: js notranslate">var pet = function(name) { // 外側の関数は変数 "name" を定義 + var getName = function() { + return name; // 内側の関数は外側の関数の変数 "name" にアクセス可能 + } + return getName; // 内側の関数を返すことで、外側の関数に公開する +} +myPet = pet('Vivie'); + +myPet(); // "Vivie" を返す +</pre> + +<p>上記のコードより複雑なコードにすることもできます。外側の関数の内部にある変数を操作するメソッドを含む、オブジェクトを返すことができます。</p> + +<pre class="brush: js notranslate">var createPet = function(name) { + var sex; + + return { + setName: function(newName) { + name = newName; + }, + + getName: function() { + return name; + }, + + getSex: function() { + return sex; + }, + + setSex: function(newSex) { + if(typeof newSex === 'string' && (newSex.toLowerCase() === 'male' || + newSex.toLowerCase() === 'female')) { + sex = newSex; + } + } + } +} + +var pet = createPet('Vivie'); +pet.getName(); // Vivie + +pet.setName('Oliver'); +pet.setSex('male'); +pet.getSex(); // male +pet.getName(); // Oliver +</pre> + +<p>上記の例で、外側の関数の変数 <code>name</code> は内側の関数からアクセスでき、また内側の関数を通さずに内側の変数へアクセスする他の方法はありません。内側の関数の内部変数は、内側の関数の安全な保存領域として振る舞います。それらは内側の関数と連動するデータを、「永続的」かつ「安全に」保持します。関数は変数を割り当てる必要さえなく、また名前を持つ必要もありません。</p> + +<pre class="brush: js notranslate">var getCode = (function(){ + var apiCode = '0]Eal(eh&2'; // 外部の関数が変更できないようにしたいコード + + return function() { + return apiCode; + }; +})(); + +getCode(); // シークレットコードを返す +</pre> + +<div class="blockIndicator note"> +<p><strong>警告:</strong> クロージャーを使用する際に注意すべき落とし穴がいくつかあります。</p> + +取り囲まれている関数で外部スコープの変数と同じ名前の変数を定義した場合、外部スコープにある変数を再び参照する方法がなくなります。(プログラムが内部スコープを終了するまで、内部スコープ変数は外部変数を「上書き」します。) + +<pre class="example-bad brush: js notranslate">var createPet = function(name) { // 外側の関数で "name" という変数を定義します。 + return { + setName: function(name) { // 内側の関数も "name" という変数を定義します + name = name; // 外側の関数で定義した "name" へどのようにしてアクセスするのか? + } + } +} +</pre> +</div> + +<h2 id="Using_the_arguments_object" name="Using_the_arguments_object">arguments オブジェクトの使用</h2> + +<p>関数の{{原語併記("引数", "argument")}}は、配列状オブジェクトで管理されます。関数内では、次のようにして渡された引数を指定することができます :</p> + +<pre class="brush: js notranslate">arguments[i] +</pre> + +<p>ここで <code>i</code> は引数の順序を表す数で、0 から始まります。関数に渡された第 1 引数は <code>arguments[0]</code> となります。引数のトータルの数は <code>arguments.length</code> で表されます。</p> + +<p><code>arguments</code> オブジェクトを使用すると、宣言時の引数の数よりも多くの引数を用いて関数を呼び出すことができます。これによって関数に渡す引数の数が前もってわからない場合にしばしば役立ちます。<code>arguments.length</code> を使用することで、実際に関数に渡された引数の数を特定することができます。そして、<code>arguments</code> オブジェクトを使用して各引数にアクセスできます。</p> + +<p>例えば、複数の文字列を連結する関数を考えます。この関数の引数は、連結するアイテムを区切るのに用いる文字列のみです。この関数は次のように定義されています :</p> + +<pre class="brush: js notranslate">function myConcat(separator) { + var result = '', // リストを初期化する + var i; + // 引数について繰り返し + for (i = 1; i < arguments.length; i++) { + result += arguments[i] + separator; + } + return result; +} +</pre> + +<p>この関数に引数をいくつも渡すことができます。そして、各引数を文字列の "リスト" に連結します:</p> + +<pre class="brush: js notranslate">// "red, orange, blue, " を返す +myConcat(', ', 'red', 'orange', 'blue'); + +// "elephant; giraffe; lion; cheetah; " を返す +myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah'); + +// "sage. basil. oregano. pepper. parsley. " を返す +myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley'); +</pre> + +<div class="note"> +<p><strong>注記 :</strong> 変数 <code>arguments</code> は "配列状の変数" であり、配列ではありません。これは数値のインデックスと <code>length</code> プロパティがあることで、配列状となってはいます。しかし、配列操作のメソッドのすべては持っていません。</p> +</div> + +<p>さらなる情報については、JavaScript リファレンスの {{jsxref("Function")}} オブジェクトをご覧ください。</p> + +<h2 id="Function_parameters" name="Function_parameters">関数の引数</h2> + +<p>ECMAScript 2015 から、新しい形の引数が 2 つあります。それが<em>デフォルト引数</em>と<em>残余引数</em>です。</p> + +<h3 id="Default_parameters" name="Default_parameters">デフォルト引数</h3> + +<p>JavaScript では、関数の引数はデフォルトで <code>undefined</code> となります。しかし、別のデフォルト値が設定されていれば便利だという状況もあるでしょう。デフォルト引数がここで役に立ちます。</p> + +<h4 id="Without_default_parameters_pre-ECMAScript_2015" name="Without_default_parameters_pre-ECMAScript_2015">デフォルト引数なし(ECMAScript 2015 以前)</h4> + +<p>以前、デフォルト値を設定する一般的な方法は、関数の本体で引数の値をテストし、<code>undefined</code> だった場合にある値を割り当てる、というものでした。</p> + +<p>以下の例では、呼び出しの際に <code>b</code> に値が割り当てられない場合、<code>a*b</code> の評価の際に <code>b</code> の値は <code>undefined</code> となるため、<code>multiply</code> を呼び出すと <code>NaN</code> が返されます。しかしながら、例の 2 行目でこの問題を回避しています :</p> + +<pre class="brush: js notranslate">function multiply(a, b) { + b = typeof b !== 'undefined' ? b : 1; + + return a * b; +} + +multiply(5); // 5 +</pre> + +<h4 id="With_default_parameters_post-ECMAScript_2015" name="With_default_parameters_post-ECMAScript_2015">デフォルト引数あり(ECMAScript 2015 以降)</h4> + +<p><em>デフォルト引数</em>を使えば、関数本体での引数チェックはもう必要ありません。これからは、関数の最初で単純に <code>b</code> に <code>1</code> を代入することができます :</p> + +<pre class="brush: js notranslate">function multiply(a, b = 1) { + return a * b; +} + +multiply(5); // 5</pre> + +<p>詳細については、リファレンスの「<a href="/ja/docs/Web/JavaScript/Reference/Functions/Default_parameters">デフォルト引数</a>」をご覧ください。</p> + +<h3 id="Rest_parameters" name="Rest_parameters">残余引数</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Functions/rest_parameters">残余引数</a>の構文によって、不特定多数の引数を配列のように表すことができます。</p> + + +<p>次の例では、2 つ目から最後までの引数をまとめるのに<em>残余引数</em>を使っています。そして最初の引数を使って乗算します。(ここでは次の章で紹介するアロー関数を使っています。)</p> + +<pre class="brush: js notranslate">function multiply(multiplier, ...theArgs) { + return theArgs.map(x => multiplier * x); +} + +var arr = multiply(2, 1, 2, 3); +console.log(arr); // [2, 4, 6]</pre> + +<h2 id="Arrow_functions" name="Arrow_functions">アロー関数</h2> + +<p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions">アロー関数式</a>(以前は、そして現在は正しくないが<strong>ファットアロー関数</strong>としても知られる)は関数式と比較してより短い構文を持ち、<code><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/this">this</a></code>、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/super">super</a>、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/new.target">new.target</a> の値を持ちません。アロー関数は常に無名関数です。hacks.mozilla.org によるこのブログ記事もご覧ください : "<a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">ES6 In Depth: Arrow functions</a>"</p> + +<p>アロー関数の導入には 2 つの要素が絡んでいます。それは<em>短縮形の関数</em>と <code>this</code> を<em>束縛しない</em>ことです。</p> + +<h3 id="Shorter_functions" name="Shorter_functions">短縮形の関数</h3> + +<p>関数パターンによっては、短縮形の関数がうってつけです。比較してみましょう :</p> + +<pre class="brush: js notranslate">var a = [ + 'Hydrogen', + 'Helium', + 'Lithium', + 'Beryllium' +]; + +var a2 = a.map(function(s) { return s.length; }); + +console.log(a2); // logs [8, 6, 7, 9] + +var a3 = a.map(s => s.length); + +console.log(a3); // logs [8, 6, 7, 9] +</pre> + +<h3 id="No_separate_this" name="No_separate_this">別々の <code>this</code> はない</h3> + +<p>アロー関数の導入以前は、すべての新しい関数には自身の <a href="https://developer.mozilla.org/jadocs/Web/JavaScript/Reference/Operators/this">this</a> 値が定義されています(コンストラクターの場合は新しいオブジェクトに、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Strict_mode">strict モード</a> の関数呼び出しの場合は undefined に、関数が「オブジェクトのメソッド」として呼び出された場合はその基底オブジェクトに、といったように)。これはオブジェクト指向プログラミングにとっては厄介です。</p> + +<pre class="brush: js notranslate">function Person() { + // この Person() コンストラクタは自身を `this` と定義します。 + this.age = 0; + + setInterval(function growUp() { + // Strict モードでない場合、この growUp() 関数は + // Person() コンストラクタによる定義とは異なり、 + // グローバルオブジェクトを `this` として定義します。 + this.age++; + }, 1000); +} + +var p = new Person();</pre> + +<p>ECMAScript 3/5 では、<code>this</code> の値をアクセス可能な別の値に割り当てることでこの問題を解決します。</p> + +<pre class="brush: js notranslate">function Person() { + var self = this; // `self` の代わりに `that` を選ぶ人もいます。 + // どちらか一方を選び、そちらだけを使うようにしましょう。 + self.age = 0; + + setInterval(function growUp() { + // このコールバックは、その値が期待通りのオブジェクトを指す + // 変数 `self` を参照している。 + self.age++; + }, 1000); +}</pre> + +<p>代わりに、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">束縛関数</a>を使って変数を束縛すれば <code>growUp()</code> 関数に適切な <code>this</code> を渡すことができます。</p> + +<p>アロー関数は自身の <code>this</code> を持ちません、つまり関数を取り囲む実行コンテキストの <code>this</code> の値が使われます。このため、下記のコードでは、<code>setInterval</code> に渡される関数内の <code>this</code> は、それを取り囲む関数の <code>this</code> と同じ値を持ちます:</p> + +<pre class="brush: js notranslate">function Person(){ + this.age = 0; + + setInterval(() => { + this.age++; // `this` は的確に person オブジェクトを参照する + }, 1000); +} + +var p = new Person();</pre> + +<h2 id="Predefined_functions" name="Predefined_functions">定義済み関数</h2> + +<p>JavaScript には、定義済みのトップレベル関数が数種類あります :</p> + +<dl> + <dt>{{jsxref("Global_Objects/eval", "eval()")}}</dt> + <dd> + <p><code><strong>eval()</strong></code> メソッドは文字列として書き表された JavaScript のコードを評価します。</p> + </dd> + <dt>{{jsxref("Global_Objects/uneval", "uneval()")}}</dt> + <dd> + <p><code><strong>uneval()</strong></code> メソッドは{{jsxref("Object","オブジェクト","","true")}}のソースコードを表す文字列を生成します。</p> + </dd> + <dt>{{jsxref("Global_Objects/isFinite", "isFinite()")}}</dt> + <dd> + <p>このグローバル関数 <code><strong>isFinite()</strong></code> は渡された値が有限数であるかを判定します。必要であれば、引数は初めに数へと変換されます。</p> + </dd> + <dt>{{jsxref("Global_Objects/isNaN", "isNaN()")}}</dt> + <dd> + <p><code><strong>isNaN()</strong></code> 関数は値が {{jsxref("Global_Objects/NaN", "NaN")}}(非数)であるかどうかを判定します。注記 : <code>isNaN</code> 関数内での強制型変換は<a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/isNaN#Description">変わったルール</a>を持っています。値が非数であるかを判定するには、代わりに ECMAScript 2015 で定義された {{jsxref("Number.isNaN()")}} か、<code><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/typeof">typeof</a></code> を使うことができます。</p> + </dd> + <dt>{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}</dt> + <dd> + <p><code><strong>parseFloat()</strong></code> 関数は引数の文字列をパースして浮動小数点数を返します。</p> + </dd> + <dt>{{jsxref("Global_Objects/parseInt", "parseInt()")}}</dt> + <dd> + <p><code><strong>parseInt()</strong></code> 関数は引数の文字列をパースして指定された基数(数学的記数法における基数)による整数を返します。</p> + </dd> + <dt>{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}</dt> + <dd> + <p><code><strong>decodeURI()</strong></code> 関数は前もって {{jsxref("Global_Objects/encodeURI", "encodeURI")}} 関数によって、あるいは同様の方法で作られた{原語併記("統一資源識別子","Uniform Resource Identifier, URI"}} をデコードします。</p> + </dd> + <dt>{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}</dt> + <dd> + <p><code><strong>decodeURIComponent()</strong></code> メソッドは前もって {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} によって、あるいは同様の方法で作られた統一資源識別子 (URI) をデコードします。</p> + </dd> + <dt>{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}</dt> + <dd> + <p><code><strong>encodeURI()</strong></code> メソッドは特定の文字をそれぞれ UTF-8 文字エンコーディングで表された 1 文字から 4 文字のエスケープシーケンス(サロゲートペア文字からなる文字にのみ 4 文字のエスケープシーケンスが必要)に置き換えることで統一資源識別子 (URI) をエンコードします。</p> + </dd> + <dt>{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}</dt> + <dd> + <p><code><strong>encodeURIComponent()</strong></code> メソッドは特定の文字をそれぞれ UTF-8 文字エンコーディングで表された 1 文字から 4 文字のエスケープシーケンス(サロゲートペア文字からなる文字にのみ 4 文字のエスケープシーケンスが必要)に置き換えることで統一資源識別子 (URI) コンポーネントをエンコードします。</p> + </dd> + <dt>{{jsxref("Global_Objects/escape", "escape()")}}</dt> + <dd> + <p>廃止予定の <code><strong>escape()</strong></code> メソッドはある文字列を 16 進数によるエスケープシーケンスで置換した新しい文字列を計算します。代わりに {{jsxref("Global_Objects/encodeURI", "encodeURI")}} か {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} を使用してください。</p> + </dd> + <dt>{{jsxref("Global_Objects/unescape", "unescape()")}}</dt> + <dd> + <p>廃止予定の <code><strong>unescape()</strong></code> メソッドはある文字列中の 16 進数によるエスケープシーケンスを、それが表す所定の文字に置換した新しい文字列を計算します。エスケープシーケンスは {{jsxref("Global_Objects/escape", "escape")}} といった関数によって提供されているかもしれません。<code>unescape()</code> は廃止予定なので、代わりに {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} か {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} を使用してください。</p> + </dd> +</dl> + +<p>{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}</p> diff --git a/files/ja/web/javascript/guide/grammar_and_types/index.html b/files/ja/web/javascript/guide/grammar_and_types/index.html new file mode 100644 index 0000000000..b32688e6d7 --- /dev/null +++ b/files/ja/web/javascript/guide/grammar_and_types/index.html @@ -0,0 +1,762 @@ +--- +title: 文法とデータ型 +slug: Web/JavaScript/Guide/Grammar_and_types +tags: + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Grammar_and_types +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}</div> + +<p class="summary">この節では JavaScript の基本文法、変数宣言、データ型、リテラルについて説明します。</p> + +<h2 id="Basics" name="Basics">基本</h2> + +<p>JavaScript は Java, C, C++ から構文の多くを取り入れていますが、Awk, Perl, Python からも影響を受けています。</p> + +<p>また、JavaScript は<strong>大文字と小文字を区別</strong>し、また <strong>Unicode</strong> 文字セットを使用しています。例えば、Früh という単語 (ドイツ語で "early" という意味) を変数名として使用することができます。</p> + +<pre class="brush: js notranslate">let Früh = "foobar"</pre> + +<p>ただし、JavaScript は大文字と小文字を区別するので、<code>früh</code> という変数は <code>Früh</code> と同じではありません。</p> + +<p>JavaScript では、命令は{{Glossary("Statement", "文")}} (statement) と呼ばれ、セミコロン (;) によって区切られています。</p> + +<p>文が単独の行で書かれている場合、文の後にセミコロンは必要ではありません。しかし、行の中に複数の文が必要な場合は、セミコロンで区切る<em>必要</em>があります。</p> + +<div class="blockIndicator note"> +<p>ECMAScript も文末に自動的にセミコロンを挿入する規則があります (<a href="/ja/docs/Web/JavaScript/Reference/Lexical_grammar#Automatic_semicolon_insertion">ASI</a>)。(詳しくは、JavaScript の <a href="/ja/docs/Web/JavaScript/Reference/Lexical_grammar">字句文法</a>についての詳細なリファレンスを参照してください。)</p> +</div> + +<p>必須ではないとしても、文の後に常にセミコロンを記述することをお勧めします。これによって、コード中にバグが発生する機会を減らすことができます。</p> + +<p>JavaScript のソーステキストは左から右にスキャンされ、<em>トークン</em>、<em>制御文字</em>、<em>改行文字</em>、<em>コメント</em>、{{glossary("whitespace", "ホワイトスペース")}}等の入力要素の並びに変換されます。(空白、タブ、改行はホワイトスペースとみなされます。)</p> + +<h2 id="Comments" name="Comments">コメント</h2> + +<p><strong>コメント</strong>の構文は C++ やその他の多くの言語と一緒です。</p> + +<pre class="brush: js notranslate">// 一行のコメント + +/* もっと長い、 + 複数行からなるコメント + */ + +/* ただし、/* 入れ子のコメントは */ できず、SyntaxError となります */ +</pre> + +<p>コメントはホワイトスペースのように扱われ、スクリプトの実行から除外されます。</p> + +<div class="blockIndicator note"> +<p><strong>注</strong>: 一部の JavaScript ファイルの先頭で、<code>#!/usr/bin/env node</code> のような第三の種類のコメントを見かけることもあるかもしれません。</p> + +<p>これは<strong>ハッシュバンコメント</strong>構文と呼ばれ、スクリプトの実行に使用したい特定の JavaScript エンジンへのパスを指定するのに使用される特殊なコメントです。詳しくは<a href="/ja/docs/Web/JavaScript/Reference/Lexical_grammar#Hashbang_comments">ハッシュバンコメント</a>を参照してください。</p> +</div> + +<h2 id="Declarations" name="Declarations">宣言</h2> + +<p>JavaScript には変数を宣言する方法が 3種類あります。</p> + +<dl> + <dt>{{jsxref("Statements/var", "var")}}</dt> + <dd>変数を宣言し、ある値に初期化することもできる。</dd> + <dt>{{jsxref("Statements/let", "let")}}</dt> + <dd>ブロックスコープのローカル変数を宣言し、ある値に初期化することもできる。</dd> + <dt>{{jsxref("Statements/const", "const")}}</dt> + <dd>ブロックスコープで読み取り専用の名前付き定数を宣言する。</dd> +</dl> + +<h3 id="Variables" name="Variables">変数</h3> + +<p>変数はアプリケーションで値を表す記号的な名前として使用します。変数の名前は{{Glossary("Identifier", "識別子")}}とも呼ばれ、一定のルールに従わなくてはなりません。</p> + +<p>JavaScript の識別子は必ず文字、アンダースコア (<code>_</code>)、あるいはドル記号 (<code>$</code>) から始まらなくてはなりません。続く文字には数字 (<code>0</code>–<code>9</code>) も使用できます。</p> + +<p>JavaScript は大文字・小文字を区別するため、使用できる文字には "<code>A</code>" から "<code>Z</code>" (大文字) に加えて "<code>a</code>" から "<code>z</code>" (小文字) も含まれます。</p> + +<p><code>å</code> や <code>ü</code> などの ISO 8859-1 や Unicode 文字 (詳しくは<a href="https://mathiasbynens.be/notes/javascript-identifiers-es6">このブログ記事</a>を参照) も識別子に使用することができます。<a href="/ja/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals">Unicode エスケープシーケンス</a>も識別子に使用することができます。</p> + +<p><code>Number_hits</code> 、<code>temp99</code> 、<code>_name</code> などは、正しい名前の一例です。</p> + +<h3 id="Declaring_variables" name="Declaring_variables">変数の宣言</h3> + +<p>変数を宣言する方法は 2通りあります。</p> + +<ul> + <li>キーワード {{jsxref("Statements/var", "var")}} を使う (例 <code>var x = 42</code>)。この構文は、<em>実行コンテキスト</em>によって、<strong>ローカル変数</strong>と<strong>グローバル変数</strong>の両方の宣言に使用できます。</li> + <li>{{jsxref("Statements/const", "const")}} または {{jsxref("Statements/let", "let")}} キーワードを使う。例えば、<code>let y = 13</code>。この構文はブロックスコープのローカル変数を宣言することができます。(以下にある<a href="#Variable_scope">変数のスコープ</a>をご覧ください。)</li> +</ul> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">分割代入</a>構文を使用して、<a href="ja/docs/Web/JavaScript/Guide/Grammar_and_types#Object_literals">オブジェクトリテラル</a>から値を展開する変数を宣言することができます。例えば、<code>let { bar } = foo</code> とします。これは <code>bar</code> という名前の変数を作成し、オブジェクト <code>foo</code> の同名キーから対応する値を代入します。</p> + +<p>また、<code>x = 42</code> のように、単純に値を変数に代入することもできます。この形は、<strong><a href="/ja/docs/Web/JavaScript/Reference/Statements/var#Description">未宣言のグローバル</a></strong>変数を生成します。strict モードの JavaScript では警告が発生します。未宣言のグローバル変数は、よく予期しない動作を引き起こします。したがって、宣言されていないグローバル変数を使用することはお勧めしません。</p> + +<h3 id="Evaluating_variables" name="Evaluating_variables">変数の評価</h3> + +<p><code>var</code> または <code>let</code> 文を使用して初期値なしで宣言された変数は、{{jsxref("undefined")}} の値をとります。</p> + +<p>未宣言の変数にアクセスしようとすると、{{jsxref("ReferenceError")}} 例外が発生します。</p> + +<pre class="brush: js notranslate">var a; +console.log('変数 a の値は ' + a); // 変数 a の値は undefined + +console.log('変数 b の値は ' + b); // 変数 b の値は undefined +var b; +// これは後述の「変数の巻き上げ」を読むまでは謎かもしれません + +console.log('変数 c の値は ' + c); // キャッチされない ReferenceError: c が定義されていない + +let x; +console.log('変数 x の値は ' + x); // 変数 x の値は undefined + +console.log('変数 y の値は ' + y); // キャッチされない ReferenceError: y が定義されていない +let y; </pre> + +<p><code>undefined</code> を使うと変数に値が入っているかは確認できます。以下のコードでは変数 <code>input</code> に値が代入されておらず、<code><a href="/ja/docs/Web/JavaScript/Reference/Statements/if...else">if</a></code> 文は <code>true</code> と評価されます。</p> + +<pre class="brush: js notranslate">var input; +if (input === undefined) { + doThis(); +} else { + doThat(); +} +</pre> + +<p><code>undefined</code> は真偽値のコンテキストで使用されると <code>false</code> としてふるまいます。例えば以下のコードでは、<code>myArray</code> の要素が <code>undefined</code> であるために関数 <code>myFunction</code> が実行されます。</p> + +<pre class="brush: js notranslate">var myArray = []; +if (!myArray[0]) myFunction(); +</pre> + +<p><code>undefined</code> は数値のコンテキストで使用されると <code>NaN</code> に変換されます。</p> + +<pre class="brush: js notranslate">var a; +a + 2; // NaN と評価される</pre> + +<p>{{jsxref("null")}} を評価する際、数値のコンテキストでは null 値は <code>0</code> としてふるまいます。また真偽値のコンテキストでは <code>false</code> としてふるまいます。例えば、</p> + +<pre class="brush: js notranslate">var n = null; +console.log(n * 32); // log 0 をコンソールに出力 +</pre> + +<h3 id="Variable_scope" name="Variable_scope">変数のスコープ</h3> + +<p>変数を関数の外側で宣言すると、その変数はその文書のどのコードからも使用できるようになるため、<em>グローバル</em> (大域) 変数と呼ばれます。変数を関数の内部で宣言すると、その変数はその関数の中でしか使用できないため、<em>ローカル</em> (局所) 変数と呼ばれます。</p> + +<p>ECMAScript 2015 より前の JavaScript には<a href="/ja/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Block_statement">ブロック文</a>のスコープがありません。正確に言えば、ブロック内で宣言した変数はブロックを内包している<em>関数 (あるいはグローバルスコープ)</em> に対して局所化されます。</p> + +<p>例えば、以下のコードでは <code>5</code> が出力されます。これは、<code>x</code> のスコープがグローバルコンテキスト (または以下のコードが関数の中であれば関数) だからです。<code>x</code> のスコープは中間の <code>if</code> 文のブロックに限定されません。</p> + +<pre class="brush: js notranslate">if (true) { + var x = 5; +} +console.log(x); // x は 5 +</pre> + +<p>このふるまいは、<code>let</code> (ECMAScript 2015 で導入) を使うことで変わります。</p> + +<pre class="brush: js notranslate">if (true) { + let y = 5; +} +console.log(y); // ReferenceError: y が定義されていない +</pre> + +<h3 id="Variable_hoisting" name="Variable_hoisting">変数の巻き上げ</h3> + +<p>もうひとつ、JavaScript の変数にまつわる独特な点として、例外を発生させることなく後に宣言した変数を参照できる点が挙げられます。</p> + +<p>この考え方は<strong>巻き上げ</strong>として知られています。JavaScript の変数は、ある意味「巻き上げられ」、関数や文の先頭まで持ち上げられます。しかし、巻き上げられた変数は <code>undefined</code> 値を返します。そのため、変数を使用したり参照した後に宣言や初期化を行うと、<code>undefined</code> が返されたままになります。</p> + +<pre class="brush: js notranslate">/** + * 例 1 + */ +console.log(x === undefined); // true +var x = 3; + +/** + * 例 2 + */ +// undefined 値が返される +var myvar = 'my value'; + +(function() { + console.log(myvar); // undefined + var myvar = 'local value'; +})(); +</pre> + +<p>上記の例は以下と同様に解釈されます。</p> + +<pre class="brush: js notranslate">/** + * 例 1 + */ +var x; +console.log(x === undefined); // true +x = 3; + +/** + * 例 2 + */ +var myvar = 'my value'; + +(function() { + var myvar; + console.log(myvar); // undefined + myvar = 'local value'; +})(); +</pre> + +<p>巻き上げがあるため、関数内にあるすべての <code>var</code> 文は関数内で可能な限り先頭に近い位置に置くべきです。これはコードの明確さを高める最善の方法です。</p> + +<p>ECMAScript 2015 では、<code>let</code> および <code>const</code> は<strong>巻き上げが行われますが、初期化されません</strong>。ブロック内の変数宣言前に変数を参照すると、変数はブロックの先頭から宣言が処理されるまでの間、「一時的なデッドゾーン」にあるため、{{jsxref("ReferenceError")}} になります。</p> + +<pre class="brush: js notranslate">console.log(x); // ReferenceError +let x = 3;</pre> + +<h3 id="Function_hoisting" name="Function_hoisting">関数の巻き上げ</h3> + +<p>関数の場合、関数<em>宣言</em>のみが巻き上げられますが、関数<em>式</em>は巻き上げられ<em>ません</em>。</p> + +<pre class="brush: js notranslate">/* 関数宣言 */ + +foo(); // "bar" + +function foo() { + console.log('bar'); +} + + +/* 関数式 */ + +baz(); // TypeError: baz は関数ではない + +var baz = function() { + console.log('bar2'); +}; +</pre> + +<h3 id="Global_variables" name="Global_variables">グローバル変数</h3> + +<p>グローバル変数は、実際には<em>グローバルオブジェクト</em>のプロパティです。</p> + +<p>ウェブページでのグローバルオブジェクトは {{domxref("window")}} になります、そのため <code>window.<var>変数名</var></code> という構文を用いてグローバル変数の設定やアクセスができます。</p> + +<p>したがって、あるウィンドウやフレームで宣言したグローバル変数は、そのウィンドウやフレームの名前を指定することで別の <code>window</code> や <code>frame</code> からアクセスできます。例えば <code>phoneNumber</code> 変数を文書内で宣言すると、<code>iframe</code> から <code>parent.phoneNumber</code> としてその変数を参照できます。</p> + +<h3 id="Constants" name="Constants">定数</h3> + +<p>{{jsxref("Statements/const", "const")}} キーワードを用いて、読み取り専用の名前付き定数を作成できます。</p> + +<p>定数の識別子の構文は、変数の識別子の構文と同じです。識別子は文字、アンダースコア、ドル記号 (<code>$</code>) から始めなくてはならず、アルファベット、数値、アンダースコアを含めることができます。</p> + +<pre class="brush: js notranslate">const PI = 3.14; +</pre> + +<p>定数は代入によって値を変えたり、スクリプト実行中に再宣言したりすることはできません。定数はある値に初期化しなければなりません。</p> + +<p>定数のスコープルールは、<code>let</code> によるブロックスコープ変数と同じです。<code>const</code> キーワードを省略すると、その識別子は変数を表すとみなされます。</p> + +<p>以下の例のように、同一スコープ内で関数や変数と同じ名前の定数を宣言することはできません。</p> + +<pre class="brush: js notranslate">// THIS WILL CAUSE AN ERROR +function f() {}; +const f = 5; + +// この場合もエラーが発生 +function f() { + const g = 5; + var g; + + // ここには文が来る +} +</pre> + +<p>しかし、定数が代入されたオブジェクトのプロパティは保護されず、以下の文は問題なく実行できます。</p> + +<pre class="brush: js notranslate">const MY_OBJECT = {'key': 'value'}; +MY_OBJECT.key = 'otherValue';</pre> + +<p>また、配列の中身は保護されませんので、以下の文は問題なく実行できます。</p> + +<pre class="brush: js notranslate">const MY_ARRAY = ['HTML','CSS']; +MY_ARRAY.push('JAVASCRIPT'); +console.log(MY_ARRAY); //logs ['HTML','CSS','JAVASCRIPT']; +</pre> + +<h2 id="Data_structures_and_types" name="Data_structures_and_types">データ構造とデータ型</h2> + +<h3 id="Data_types" name="Data_types">データ型</h3> + +<p>最新の ECMAScript 標準では、以下の 8 つのデータ型が定義されています。</p> + +<ul> + <li>{{Glossary("Primitive", "プリミティブ型")}}のデータ型が 7 つあります。 + <ul> + <li>{{Glossary("Boolean")}} (真偽値)。<code>true</code> または <code>false</code>。</li> + <li>{{Glossary("null")}}。null 値を意味する特殊なキーワードです。(JavaScript は大文字・小文字を区別するため、<code>null</code> は <code>Null</code> や <code>NULL</code> などと同じではありません。)</li> + <li>{{Glossary("undefined")}} (未定義)。値が未定義の最上位プロパティです。</li> + <li>{{Glossary("Number")}} (数値)。整数または浮動小数点数。例えば <code>42</code> や <code>3.14159</code> など。</li> + <li>{{Glossary("BigInt")}} (長整数)。精度が自由な整数値。例えば <code>9007199254740992n</code> など。</li> + <li>{{Glossary("String")}} (文字列)。テキストの値を表す連続した文字。"Howdy" など。</li> + <li>{{Glossary("Symbol")}} (シンボル) (ECMAScript 2015 の新機能)。インスタンスが固有で不変となるデータ型。</li> + </ul> + </li> + <li>そして {{Glossary("Object")}} (オブジェクト)。</li> +</ul> + +<p>このようにデータ型の種類は比較的少ないですが、アプリケーションで便利な関数を実行することができます。整数と実数の間に明確な違いはありません。{{jsxref("Object", "オブジェクト","","true")}}と{{jsxref("Function", "関数","","true")}}も言語において基本的な要素です。オブジェクトは値を収める名前付きコンテナとして、関数はスクリプトを実行可能にする手続きとして考えることができます。</p> + +<h3 id="Data_type_conversion" name="Data_type_conversion">データ型の変換</h3> + +<p>JavaScript は<em>動的型付け</em>言語です。そのため変数宣言時にデータ型を指定する必要がなく、またスクリプト実行時に必要に応じてデータ型が自動的に変換されます。</p> + +<p>例えば以下のように変数を定義したとします。</p> + +<pre class="brush: js notranslate">var answer = 42; +</pre> + +<p>その後、同じ変数に文字列を代入できます。</p> + +<pre class="brush: js notranslate">answer = 'Thanks for all the fish...'; +</pre> + +<p>JavaScript は動的型付け方式であるため、この代入を行ってもにエラーメッセージは表示されません。</p> + +<h3 id="Numbers_and_the_operator" name="Numbers_and_the_operator">数値と '+' 演算子</h3> + +<p>数値と文字列を <code>+</code> 演算子で結合する式では、JavaScript は数値を文字列に変換します。以下の式を見てみましょう。</p> + +<pre class="brush: js notranslate">x = '答えは ' + 42 // "答えは 42" +y = 42 + ' が答え' // "42 が答え" +</pre> + +<p>それ以外の演算子がある式では、JavaScript は数値を文字列に変換<em>しません</em>。例えば以下のようになります。</p> + +<pre class="brush: js notranslate">'37' - 7 // 30 +'37' + 7 // "377" +</pre> + +<h3 id="Converting_strings_to_numbers" name="Converting_strings_to_numbers">文字列から数値への変換</h3> + +<p>数値を表す値が文字列として記憶されている場合、それを変換するメソッドがあります。</p> + +<ul> + <li id="parseInt()_and_parseFloat()">{{jsxref("parseInt", "parseInt()")}}</li> + <li>{{jsxref("parseFloat", "parseFloat()")}}</li> +</ul> + +<p><code>parseInt</code> は整数のみを返すので、小数は切り捨てられます。</p> + +<div class="blockIndicator note"> +<p>さらに、<code>parseInt</code> を使う最も良い方法は、常に基数を引数に含めるようにすることです。基数の引数は使用されている<em>基数</em>法を指定するのに使われます。</p> +</div> + +<pre class="brush: js notranslate">parseInt('101', 2) // 5</pre> + +<p>文字列から数値を取り出す代替手段は、<code>+</code> (単項プラス) 演算子を使う方法です。</p> + +<pre class="brush: js notranslate">'1.1' + '1.1' // '1.11.1' +(+'1.1') + (+'1.1') // 2.2 +// 注: 括弧は明確さのために追加したもので、必須ではありません</pre> + +<h2 id="Literals" name="Literals">リテラル</h2> + +<p>JavaScript では値の表現に<em>リテラル</em>を使います。これらは固定値であり変数ではなく、スクリプト中に直接<em>記述</em>します。本章では、以下のリテラルについて説明します :</p> + +<ul> + <li><a href="#Array_literals">配列リテラル</a></li> + <li><a href="#Boolean_literals">真偽値リテラル</a></li> + <li><a href="#Floating-point_literals">浮動小数点リテラル</a></li> + <li><a href="#Numeric_literals">数値リテラル</a></li> + <li><a href="#Object_literals">オブジェクトリテラル</a></li> + <li><a href="#RegExp_literals">正規表現リテラル</a></li> + <li><a href="#String_literals">文字列リテラル</a></li> +</ul> + +<h3 id="Array_literals" name="Array_literals">配列リテラル</h3> + +<p>配列リテラルとは、0 個以上の式のリストであり、各々の式は配列の要素を表し、角括弧 (<code>[]</code>) で括られているもののことです。配列リテラルを用いて配列を作成すると、指定された値が要素として初期化され、また配列の長さ (<code>length</code>) は指定された引数の個数に設定されます。</p> + +<p>以下の例では 3 つの要素を持ち、配列 <code>coffees</code> を長さ (<code>length</code>) 3 で作成します。</p> + +<pre class="brush: js notranslate">let coffees = ['French Roast', 'Colombian', 'Kona']; +</pre> + +<div class="note"> +<p><strong>注:</strong> 配列リテラルは<em>オブジェクト初期化子</em>の一種です。<a href="/ja/docs/Web/JavaScript/Guide/Working_with_Objects#Using_object_initializers">オブジェクト初期化子の使用</a>を参照してください。</p> +</div> + +<p>トップレベルのスクリプト内でリテラルを用いて配列を作成した場合、JavaScript は配列リテラルを含む式を評価するたびに配列を解釈します。さらに関数内で使用されたリテラルは、関数が呼び出されるたびに生成されます。</p> + +<div class="blockIndicator note"> +<p>配列リテラルは <code>Array</code> オブジェクトでもあります。<code>Array</code> オブジェクトの詳細は {{jsxref("Array")}} と<a href="/ja/docs/Web/JavaScript/Guide/Indexed_collections">インデックス付きコレクション</a>をご覧ください。</p> +</div> + +<h4 id="Extra_commas_in_array_literals" name="Extra_commas_in_array_literals">配列リテラルでの余分なカンマ</h4> + +<p>配列リテラルですべての要素を指定する必要はありません。立て続けに 2 つのカンマを置くと、配列は未指定の要素を <code>undefined</code> の値で埋めます。次の例では <code>fish</code> という配列を作成します。</p> + +<pre class="brush: js notranslate">let fish = ['Lion', , 'Angel']; +</pre> + +<p>この配列は、値を持つ要素を 2 つと空の要素を 1 つ持っています。</p> + +<ul> + <li><code>fish[0]</code> は "Lion"</li> + <li><code>fish[1]</code> は <code>undefined</code></li> + <li><code>fish[2]</code> は "Angel"</li> +</ul> + +<p>要素のリストの最後にカンマを付けた場合、そのカンマは無視されます。</p> + +<p>次の例では、配列の長さ (<code>length</code>) は 3 です。<code>myList[3]</code> は存在しません。リスト内の他のカンマはすべて、新しい要素を示します。</p> + +<div class="note"> +<p><strong>注:</strong> 末尾にカンマを置くと古いブラウザーでエラーになる場合があるので、取り除くのが最善です。</p> +</div> + +<pre class="brush: js notranslate">let myList = ['home', , 'school', ]; +</pre> + +<p>次の例では、配列の長さ (<code>length</code>) は 4 になります。<code>myList[0]</code> と <code>myList[2]</code> が抜けています。</p> + +<pre class="brush: js notranslate">let myList = [ ,'home', , 'school']; +</pre> + +<p>次の例では、配列の長さ (<code>length</code>) は 4 です。<code>myList[1]</code> と <code>myList[3]</code> が抜けています。最後のカンマのみが無視されます。</p> + +<pre class="brush: js notranslate">let myList = ['home', , 'school', , ]; +</pre> + +<p>余分なカンマの動作を理解することは、言語としての JavaScript を理解するために重要です。</p> + +<p>しかし、コードを記述する際に欠落している要素を明示的に <code>undefined</code> するようにしてください。そうすれば、コードの明確さや保守性が高まります。</p> + +<h3 id="Boolean_literals" name="Boolean_literals">真偽値リテラル</h3> + +<p>真偽値型は 2 つのリテラル値、<code>true</code> と <code>false</code> があります。</p> + +<div class="blockIndicator note"> +<p><strong>忠告:</strong> プリミティブ型の真偽値である <code>true</code> や <code>false</code> と、{{jsxref("Boolean")}} オブジェクトの <code>true</code> や <code>false</code> という値とを混同してはいけません。</p> + +<p>Boolean オブジェクトは、プリミティブな真偽値型のラッパーです。詳細は {{jsxref("Boolean")}} を参照してください。</p> +</div> + +<h3 id="Numeric_literals" name="Numeric_literals">数値リテラル</h3> + +<p>{{jsxref("Number")}} および {{jsxref("BigInt")}} 型は、10進数、16進数、8進数、2進数で書くことができます。</p> + +<ul> + <li><em>10進数</em>の数値リテラルは、先頭が <code>0</code> (ゼロ) ではない一連の数字で構成されます。</li> + <li>先頭に <code>0</code> (ゼロ) である数値リテラル、または先頭の <code>0o</code> (または <code>0O</code>) は <em>8進数</em>であることを示します。8進数の数値には、<code>0</code> から <code>7</code> の数字のみが使用できます。</li> + <li>先頭の <code>0x</code> (または <code>0X</code>) は、<em>16進数</em>であることを意味します。16進数の数値は数字 (<code>0</code> から <code>9</code>) と <code>a</code> から <code>f</code> および <code>A</code> から <code>F</code> のアルファベットで構成されます。(大文字・小文字の違いは値には影響しません。たとえば <code>0xa</code> = <code>0xA</code> = <code>10</code> で <code>0xf</code> = <code>0xF</code> = <code>15</code> です。)</li> + <li> + <p>先頭の <code>0b</code> (または <code>0B</code>) は、<em>2進数</em>であることを表します。2進数の数値は <code>0</code> と <code>1</code> の数字のみで構成されます。</p> + </li> +</ul> + +<p>数値リテラルの例は以下のようになります。</p> + +<pre class="eval notranslate">0, 117, -345, 123456789123456789n (10進数) +015, 0001, -0o77, 0o777777777777n (8進数) +0x1123, 0x00111, -0xF1A7, 0x123456789ABCDEFn (16進数) +0b11, 0b0011, -0b11, 0b11101001010101010101n (2進数) +</pre> + +<p>詳しい情報は、<a href="/ja/docs/Web/JavaScript/Reference/Lexical_grammar#Numeric_literals">字句構文リファレンスの数値リテラル</a>をご覧ください。</p> + +<h3 id="Floating-point_literals" name="Floating-point_literals">浮動小数点リテラル</h3> + +<p>浮動小数点リテラルは、以下の部分で構成されます。</p> + +<ul> + <li>符号 (先行する "<code>+</code>" または "<code>-</code>") つきの 10進数の整数部</li> + <li>小数点 ("<code>.</code>")</li> + <li>小数部 (他の 10進数)</li> + <li>指数部</li> +</ul> + +<p>指数部は、"<code>e</code>" または "<code>E</code>" の後に、符号 ( "<code>+</code>" or "<code>-</code>") を先行させることできる整数が続く形になります。浮動小数点数リテラルは少なくとも 1 つの数字と、小数点もしくは "<code>e</code>" (または "<code>E</code>") が必要です。</p> + +<p>より簡潔に書けば、次の形式になります。</p> + +<pre class="eval notranslate">[(+|-)][digits].[digits][(E|e)[(+|-)]digits] +</pre> + +<p>例えば以下の通りです。</p> + +<pre class="eval notranslate">3.1415926 +-.123456789 +-3.1E+12 +.1e-23 +</pre> + +<h3 id="Object_literals" name="Object_literals">オブジェクトリテラル</h3> + +<p>オブジェクトリテラルとは、プロパティ名とそれに関連付けられたオブジェクトの値との 0 個以上の組が波括弧 (<code>{}</code>) で囲まれたもので作られたリストです。</p> + +<div class="blockIndicator warning"> +<p><strong>オブジェクトリテラルを文の先頭で使わないようにしてください。</strong> <code>{</code> がブロックの始まりと解釈されるため、エラーや予期せぬ動作を引き起こすことになります。</p> +</div> + +<p>以下にオブジェクトリテラルの例を示します。<code>car</code> オブジェクトの最初の要素には <code>myCar</code> プロパティが定義され、新規文字列 "<code>Saturn</code>" が割り当てられています。2番目の要素、<code>getCar</code> プロパティには関数 <code>(carTypes("Honda"));</code> によって呼び出された結果が即座に割り当てられます。3番目の要素、<code>special</code> プロパティには既存の変数 (<code>sales</code>) が使われています。</p> + +<pre class="brush: js notranslate">var sales = 'Toyota'; + +function carTypes(name) { + if (name === 'Honda') { + return name; + } else { + return "Sorry, we don't sell " + name + "."; + } +} + +var car = { myCar: 'Saturn', getCar: carTypes('Honda'), special: sales }; + +console.log(car.myCar); // Saturn +console.log(car.getCar); // Honda +console.log(car.special); // Toyota +</pre> + +<p>さらに、数値リテラルや文字列リテラルをプロパティ名に使用したり、オブジェクトを別のオブジェクトの入れ子にすることができます。以下の例では、これらの機能を使用しています。</p> + +<pre class="brush: js notranslate">var car = { manyCars: {a: 'Saab', b: 'Jeep'}, 7: 'Mazda' }; + +console.log(car.manyCars.b); // Jeep +console.log(car[7]); // Mazda +</pre> + +<p>オブジェクトのプロパティには空の文字列を含むあらゆる文字列が使えます。もしプロパティ名が JavaScript で有効な{{Glossary("Identifier", "識別子")}}か数値でなければ、引用符で囲む必要があります。</p> + +<p>有効でない識別子によるプロパティ名にはドット演算子 (<code>.</code>) を使ってアクセスできませんが、配列のような表記法 ("<code>[]</code>") でアクセス、設定ができます。</p> + +<pre class="brush: js notranslate">var unusualPropertyNames = { + '': '空文字列', + '!': 'バン!' +} +console.log(unusualPropertyNames.''); // SyntaxError: Unexpected string が発生 +console.log(unusualPropertyNames['']); // 空文字列 +console.log(unusualPropertyNames.!); // SyntaxError: Unexpected token ! が発生 +console.log(unusualPropertyNames['!']); // バン!</pre> + +<h4 id="Enhanced_Object_literals" name="Enhanced_Object_literals">拡張オブジェクトリテラル</h4> + +<p>ES2015 では、オブジェクトリテラルは構築時のプロトタイプの設定に対応するよう拡張され、<code>foo: foo</code> 形式の短縮表記の値割り当て、メソッドの定義、<code>super</code> の呼び出し、式によるプロパティ名の計算ができるようになりました。</p> + +<p>同時に、オブジェクトリテラルとクラス定義が近くなり、オブジェクトベースの設計でも同じ利便性の一部から利益を得ることができます。</p> + +<pre class="brush: js notranslate">var obj = { + // __proto__ + __proto__: theProtoObj, + // 短い ‘handler: handler’ の形式 + handler, + // メソッド + toString() { + // super の呼び出し + return 'd ' + super.toString(); + }, + // 計算による (動的な) プロパティ名 + [ 'prop_' + (() => 42)() ]: 42 +}; +</pre> + +<h3 id="RegExp_literals" name="RegExp_literals">正規表現リテラル</h3> + +<p>正規表現リテラル (<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions">後で</a>詳しく定義) は、スラッシュで囲まれたパターンです。以下は正規表現リテラルの例です。</p> + +<pre class="brush: js notranslate">var re = /ab+c/;</pre> + +<h3 id="String_literals" name="String_literals">文字列リテラル</h3> + +<p>文字列リテラルとは、0文字以上の文字を二重引用符 (<code>"</code>) または単一引用符 (<code>'</code>) で括ったものです。文字列は同じ種類の引用符で括らなければなりません (つまり、どちらも単一引用符にするか、またはどちらも二重引用符にするかです)。</p> + +<p>以下が文字列リテラルの例です。</p> + +<pre class="brush: js notranslate">'foo' +"bar" +'1234' +'one line \n another line' +"John's cat" +</pre> + +<p>文字列リテラルを持つ値は、{{jsxref("String")}} オブジェクトのあらゆるメソッドを呼び出すことができます。JavaScript は自動的に文字列リテラルを一時的な String オブジェクトに変換し、メソッドを呼び出して、その後一時的に作られた String オブジェクトを破棄します。<code>String.length</code> プロパティを文字列リテラルで用いることもできます。</p> + +<pre class="brush: js notranslate">// ホワイトスペースを含む文字列の文字の数を出力する。 +console.log("John's cat".length) // この場合は 10 が出力される。 +</pre> + +<p>ECMAScript 2015 では、<em>テンプレートリテラル</em>も利用することができます。テンプレートリテラルは、二重引用符や単一引用符の代わりに逆引用符 (<code>`</code>) (<a class="external external-icon" href="https://en.wikipedia.org/wiki/Grave_accent" rel="noopener">grave accent</a>) で囲まれたものです。</p> + +<p>テンプレート文字列は文字列の構築に糖衣構文を利用することができます。これは Perl や Python などの文字列補完機能に似ています。</p> + +<p>また、文字列の構築をカスタマイズして、インジェクション攻撃を防いだり文字列コンテンツのより高水準のデータ構造を構築したりするためにタグを追加することができます。</p> + +<pre class="brush: js notranslate">// 基本的な文字列リテラルの作成 +`In JavaScript '\n' is a line-feed.` + +// 複数行の文字列 +`In JavaScript, template strings can run + over multiple lines, but double and single + quoted strings cannot.` + +// 文字列補完 +var name = 'Bob', time = 'today'; +`Hello ${name}, how are you ${time}?` + +// 置換や構築を解釈するために使用される HTTP リクエストの接頭辞を構築 +POST`http://foo.org/bar?a=${a}&b=${b} + Content-Type: application/json + X-Credentials: ${credentials} + { "foo": ${foo}, + "bar": ${bar}}`(myOnReadyStateChangeHandler);</pre> + +<p>特に <code>String</code> オブジェクトを使う必要がない場合は、文字列リテラルを使うようにしてください。詳細は {{jsxref("String")}} をご覧ください。</p> + +<h4 id="Using_special_characters_in_strings" name="Using_special_characters_in_strings">文字列での特殊文字の使用</h4> + +<p>文字列では、通常の文字に加えて特殊文字も使用できます。次の例をご覧ください。</p> + +<pre class="brush: js notranslate">'one line \n another line' +</pre> + +<p>ここで、JavaScript の文字列で使用できる特殊文字の表を示します。</p> + +<table class="standard-table"> + <caption>表: JavaScript の特殊文字</caption> + <thead> + <tr> + <th scope="col">文字</th> + <th scope="col">意味</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>\0</code></td> + <td>ヌル文字</td> + </tr> + <tr> + <td><code>\b</code></td> + <td>バックスペース</td> + </tr> + <tr> + <td><code>\f</code></td> + <td>改ページ</td> + </tr> + <tr> + <td><code>\n</code></td> + <td>改行</td> + </tr> + <tr> + <td><code>\r</code></td> + <td>復帰</td> + </tr> + <tr> + <td><code>\t</code></td> + <td>タブ</td> + </tr> + <tr> + <td><code>\v</code></td> + <td>垂直タブ</td> + </tr> + <tr> + <td><code>\'</code></td> + <td>アポストロフィまたは単一引用符</td> + </tr> + <tr> + <td><code>\"</code></td> + <td>二重引用符</td> + </tr> + <tr> + <td><code>\\</code></td> + <td>バックスラッシュ (\)</td> + </tr> + <tr> + <td><code>\<em>XXX</em></code></td> + <td><code>0</code> から <code>377</code> までの 3桁の 8進数 <em>XXX</em> で指定された、Latin-1 エンコーディングの文字。<br> + 例えば、<code>\251</code> は著作権記号を示します。</td> + </tr> + <tr> + </tr> + <tr> + <td><code>\x<em>XX</em></code></td> + <td> + <p><code>00</code> から <code>FF</code> までの 2桁の 16進数 <em>XX</em> で指定された、Latin-1 エンコーディングの文字。<br> + 例えば、<code>\xA9</code> は著作権記号を示します。</p> + </td> + </tr> + <tr> + </tr> + <tr> + <td><code>\u<em>XXXX</em></code></td> + <td>4桁の 16 進数 <em>XXXX</em> で指定された Unicode 文字。<br> + 例えば、<code>\u00A9</code> は著作権記号を示します。<a href="/ja/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals">Unicode エスケープシーケンス</a>をご覧ください。</td> + </tr> + <tr> + <td><code>\u<em>{XXXXX}</em></code></td> + <td>Unicode コードポイントエスケープです。<br> + 例えば <code>\u{2F804}</code> は単純な Unicode エスケープである <code>\uD87E\uDC04</code> と同じです。</td> + </tr> + </tbody> +</table> + +<h4 id="Escaping_characters" name="Escaping_characters">文字のエスケープ</h4> + +<p>上記の表に掲載されていない文字は直前にバックスラッシュをつけても無視されますが、こうした使い方は非推奨であり使用を避けるべきです。</p> + +<p>バックスラッシュを直前につけることで、引用符を文字列に含めることができます。これは引用符の<em>エスケープ</em>と呼ばれます。例えば以下のようにします。</p> + +<pre class="brush: js notranslate">var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service."; +console.log(quote); +</pre> + +<p>この結果は次のようになります。</p> + +<pre class="eval notranslate">He read "The Cremation of Sam McGee" by R.W. Service. +</pre> + +<p>文字列にバックスラッシュそのものを含めるには、バックスラッシュのエスケープが必要です。例えば、文字列に <code>c:\temp</code> というファイルパスを代入するには、以下のようにします。</p> + +<pre class="brush: js notranslate">var home = 'c:\\temp'; +</pre> + +<p>改行の直前にバックスラッシュを置くことで、改行をエスケープすることもできます。バックスラッシュと改行の両方が、文字列の値から取り除かれます。</p> + +<pre class="brush: js notranslate">var str = 'this string \ +is broken \ +across multiple \ +lines.' +console.log(str); // この文字列は複数行にわたって分解されます。 +</pre> + +<p>JavaScript には「ヒアドキュメント」構文はありませんが、各行の末尾に改行のエスケープ表記とエスケープした改行を置くことで似たことができます。</p> + +<pre class="brush: js notranslate">var poem = +'Roses are red,\n\ +Violets are blue.\n\ +Sugar is sweet,\n\ +and so is foo.' +</pre> + +<p>ECMAScript 2015 では<a href="/ja/docs/Web/JavaScript/Reference/template_strings"><strong>テンプレートリテラル</strong></a>と呼ばれる新しい種類のリテラルが導入されました。これによって複数行の文字列を含む多数の新機能が利用できるようになりました。</p> + +<pre class="brush: js notranslate" dir="rtl">var poem = +`Roses are red, +Violets are blue. +Sugar is sweet, +and so is foo.` </pre> + +<h2 id="More_information" name="More_information">関連情報</h2> + +<p>本章では宣言とデータ型についての基本文法に重点を置いています。JavaScript の言語構成についてより詳しく知りたければ、当ガイドの以下に挙げた章をご覧ください。</p> + +<ul> + <li><a href="/ja/docs/Web/JavaScript/Guide/Control_flow_and_error_handling">制御フローとエラー処理</a></li> + <li><a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration">ループと反復処理</a></li> + <li><a href="/ja/docs/Web/JavaScript/Guide/Functions">関数</a></li> + <li><a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators">式と演算子</a></li> +</ul> + +<p>次章では、制御フローの構造とエラー処理について見ていきます。</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}</p> diff --git a/files/ja/web/javascript/guide/index.html b/files/ja/web/javascript/guide/index.html new file mode 100644 index 0000000000..9e89757ae6 --- /dev/null +++ b/files/ja/web/javascript/guide/index.html @@ -0,0 +1,138 @@ +--- +title: JavaScript ガイド +slug: Web/JavaScript/Guide +tags: + - Guide + - JavaScript + - 'l10n:priority' + - ガイド +translation_of: Web/JavaScript/Guide +--- +<div>{{jsSidebar("JavaScript Guide")}}</div> + +<p class="summary">この JavaScript ガイドでは、<a href="/ja/docs/Web/JavaScript">JavaScript</a> の使い方を紹介し、この言語の概要を説明します。JavaScript の機能についてもっと知りたい場合は、<a href="/ja/docs/Web/JavaScript/Reference">JavaScript リファレンス</a> を参照してください。</p> + +<h2 id="Chapters" name="Chapters">目次</h2> + +<p>このガイドは、いくつかの章に分かれています。</p> + +<ul class="card-grid"> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Introduction">入門編</a></span> + + <p><a href="/ja/docs/Web/JavaScript/Guide/Introduction#Where_to_find_JavaScript_information">このガイドについて</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Introduction#What_is_JavaScript">JavaScript について</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Introduction#JavaScript_and_Java">JavaScript と Java</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Introduction#JavaScript_and_the_ECMAScript_Specification">ECMAScript</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Introduction#Getting_started_with_JavaScript">ツール</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Introduction#Hello_world">Hello World</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types">文法とデータ型</a></span> + <p><a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Basics">基本構文とコメント</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Declarations">宣言</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Variable_scope">変数のスコープ</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Variable_hoisting">変数の巻き上げ</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Data_structures_and_types">データ構造とデータ型</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Literals">リテラル</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Control_flow_and_error_handling">制御フローとエラー処理</a></span> + <p><code><a href="/ja/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#if...else_statement">if...else</a></code><br> + <code><a href="/ja/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#switch_statement">switch</a></code><br> + <a href="/ja/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Exception_handling_statements"><code>try</code>/<code>catch</code>/<code>throw</code></a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Utilizing_Error_objects">エラーオブジェクト</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration">ループと反復処理</a></span> + <p><code><a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration#for_statement">for</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration#while_statement">while</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration#do...while_statement">do...while</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration#break_statement">break</a>/<a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration#continue_statement">continue</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration#for...in_statement">for..in</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration#for...of_statement">for..of</a></code></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Functions">関数</a></span> + + <p><a href="/ja/docs/Web/JavaScript/Guide/Functions#Defining_functions">関数の定義</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Functions#Calling_functions">関数の呼び出し</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Functions#Function_scope">関数のスコープ</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Functions#Closures">クロージャ</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Functions#Using_the_arguments_object">実引数</a> と <a href="/ja/docs/Web/JavaScript/Guide/Functions#Function_parameters">仮引数</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Functions#Arrow_functions">アロー関数</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators">式と演算子</a></span> + <p><a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment_operators">代入演算子</a> と <a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#Comparison_operators">比較演算子</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#Arithmetic_operators">算術演算子</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators">ビット演算子</a> と <a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical_operators">論理演算子</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Expressions_and_Operators#Conditional_(ternary)_operator">条件演算子</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Numbers_and_dates">数値と日付</a></span> <a href="/ja/docs/Web/JavaScript/Guide/Numbers_and_dates#Numbers">数値リテラル</a> + <p><a href="/ja/docs/Web/JavaScript/Guide/Numbers_and_dates#Number_object"><code>Number</code> オブジェクト</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Numbers_and_dates#Math_object"><code>Math</code> オブジェクト</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Numbers_and_dates#Date_object"><code>Date</code> オブジェクト</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Text_formatting">テキスト処理</a></span> + <p><a href="/ja/docs/Web/JavaScript/Guide/Text_formatting#String_literals">文字列リテラル</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Text_formatting#String_objects"><code>String</code> オブジェクト</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Text_formatting#Multi-line_template_literals">テンプレートリテラル</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Text_formatting#Internationalization">国際化</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions">正規表現</a></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Indexed_collections">インデックス付きコレクション</a></span> + + <p><a href="/ja/docs/Web/JavaScript/Guide/Indexed_collections#Array_object">配列</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Indexed_collections#Typed_Arrays">型付き配列</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Keyed_collections">キー付きコレクション</a></span> + <p><code><a href="/ja/docs/Web/JavaScript/Guide/Keyed_collections#Map_object">Map</a></code><br> + <code><a href="/ja/docs/Web/JavaScript/Guide/Keyed_collections#WeakMap_object">WeakMap</a></code><br> + <code><a href="/ja/docs/Web/JavaScript/Guide/Keyed_collections#Set_object">Set</a></code><br> + <code><a href="/ja/docs/Web/JavaScript/Guide/Keyed_collections#WeakSet_object">WeakSet</a></code></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Working_with_Objects">オブジェクトを利用する</a></span> + <p><a href="/ja/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties">オブジェクトとそのプロパティ</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Working_with_Objects#Creating_new_objects">新しいオブジェクトの作成</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_methods">メソッドの定義</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters">getter と setter</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Details_of_the_Object_Model">オブジェクトモデルの詳細</a></span> + <p><a href="/ja/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Class-based_vs._prototype-based_languages">プロトタイプベース言語</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Creating_the_hierarchy">階層の作成</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Property_inheritance_revisited">継承</a></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Using_promises">Promiseを使う</a></span> + + <p><a href="/ja/docs/Web/JavaScript/Guide/Using_promises#Guarantees">保証</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Using_promises#Chaining">Promise チェーン</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Using_promises#Error_propagation">エラーの伝搬</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Using_promises#Composition">合成 (Composition)</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Using_promises#Timing">タイミング</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Iterators_and_Generators">イテレータとジェネレータ</a></span> + <p><a href="/ja/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterators">イテレータ</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterables">反復可能 (イテラブル)</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generators">ジェネレータ</a></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Meta_programming">メタプログラミング</a></span> + <p><code><a href="/ja/docs/Web/JavaScript/Guide/Meta_programming#Proxies">プロキシ</a></code><br> + <a href="/ja/docs/Web/JavaScript/Guide/Meta_programming#Handlers_and_traps">ハンドラとトラップ</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Meta_programming#Revocable_Proxy">取り消し可能 Proxy</a><br> + <code><a href="/ja/docs/Web/JavaScript/Guide/Meta_programming#Reflection">Reflect</a></code></p> + </li> + <li><span><a href="/ja/docs/Web/JavaScript/Guide/Modules">JavaScript モジュール</a></span> + <p><a href="/ja/docs/Web/JavaScript/Guide/Modules#Exporting_module_features">エクスポート</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Modules#Importing_features_into_your_script">インポート</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Modules#Default_exports_versus_named_exports">デフォルトエクスポート</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Modules#Renaming_imports_and_exports">名前を変更する</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Modules#Aggregating_modules">モジュールの集約</a><br> + <a href="/ja/docs/Web/JavaScript/Guide/Modules#Dynamic_module_loading">動的なモジュールの読み込み</a></p> + </li> +</ul> + +<p>{{Next("Web/JavaScript/Guide/Introduction")}}</p> diff --git a/files/ja/web/javascript/guide/indexed_collections/index.html b/files/ja/web/javascript/guide/indexed_collections/index.html new file mode 100644 index 0000000000..6675d1a97c --- /dev/null +++ b/files/ja/web/javascript/guide/indexed_collections/index.html @@ -0,0 +1,598 @@ +--- +title: インデックス付きコレクション +slug: Web/JavaScript/Guide/Indexed_collections +tags: + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Indexed_collections +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}</div> + +<p class="summary">この節では、インデックス値により順序付けされたデータのコレクションを紹介します。配列、{{jsxref("Array")}} オブジェクト、{{jsxref("TypedArray")}} オブジェクトなどの配列用の構造体があります。</p> + +<h2 id="Array_object" name="Array_object"><code>Array</code> オブジェクト</h2> + +<p><em>配列</em>は名前やインデックスで参照できる値からなる順序集合です。例えば、<code>emp</code> という配列を作成し、従業員番号と従業員の名前を対応付けることができます。つまり、<code>emp[1]</code> が従業員番号 1 、<code>emp[2]</code> が従業員番号 2 、のようになります。</p> + +<p>JavaScript は明確な配列データ型を持っていません。しかし、アプリケーションで配列として機能する定義済みの <code>Array</code> オブジェクトとそのメソッドを利用できます。<code>Array</code> オブジェクトには配列の結合、反転、ソートなど様々な方法で配列を操作するメソッドがあります。また、配列の長さを特定するプロパティや、正規表現で使用するプロパティなどがあります。</p> + +<h3 id="Creating_an_array" name="Creating_an_array">配列の生成</h3> + +<p>以下の文は同じ配列を生成します。</p> + +<pre class="brush: js notranslate">let arr = new Array(<var>element0</var>, <var>element1</var>, ..., <var>elementN</var>) +let arr = Array(<var>element0</var>, <var>element1</var>, ..., <var>elementN</var>) +let arr = [<var>element0</var>, <var>element1</var>, ..., <var>elementN</var>] +</pre> + +<p><code>element0, element1, ..., elementN</code> は配列要素になる値から構成されるリストです。これらの値が指定されると、この配列の要素はそれらの値に初期化されます。配列の <code>length</code> プロパティは引数の数に設定されます。</p> + +<p>角括弧による構文は「配列リテラル」または「配列初期化子」と呼ばれます。この構文はその他の形式による配列作成よりも短いため、一般的に好まれる方法です。詳細については、<a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Array_literals">配列リテラル</a>をご覧ください。</p> + +<p>長さがゼロではないが項目のない配列を作成するには、以下の方法が使用できます。</p> + +<pre class="brush: js notranslate">// これはこ... +let arr = new Array(<var>arrayLength</var>) + +// ...このような結果になります +let arr = Array(<var>arrayLength</var>) + + +// これも同じ効果があります +let arr = [] +arr.length = <var>arrayLength</var> +</pre> + +<div class="note"> +<p><strong>注:</strong> 上記のコードでは、<code>arrayLength</code> は <code>Number</code>(数値)である必要があります。さもないと、(指定した値の)単一の要素を持つ配列が生成されます。<code>arr.length</code> を呼び出すと <code>arrayLength</code> が返されますが、実際には配列は空要素 (undefined) で構成されます。この配列で {{jsxref("Statements/for...in","for...in")}} ループを実行しても、配列の要素は返されません。</p> +</div> + +<p>上記のように新規に定義した変数に割り当てるだけでなく、新規または既存のオブジェクトのプロパティに配列を割り当てることができます。</p> + +<pre class="brush: js notranslate">let obj = {} +// ... +obj.prop = [element0, element1, ..., elementN] + +// または +let obj = {prop: [element0, element1, ...., elementN]} +</pre> + +<p>単一の要素で配列を初期化しようとして、その要素が <code>Number</code> である場合、角括弧の構文を使用する必要があります。単一の <code>Number</code> 値が Array() コンストラクタや関数に渡されると、単一の数値要素としてではなく、<code>arrayLength</code> として解釈されます。</p> + +<pre class="brush: js notranslate">let arr = [42] // 42 という数の要素を + // 1 個だけ持つ配列が作られます。 + +let arr = Array(42) // 要素がなく、arr.length が + // 42 に設定された配列が作られます。 + // + // 以下のコードと同様です。 +let arr = [] +arr.length = 42 +</pre> + +<p><code>N</code> の値が小数部分がゼロではない実数である場合、<code>Array(N)</code> を呼び出すと、結果は <code>RangeError</code> になります。以下の例ではこの動作を示します。</p> + +<pre class="brush: js notranslate">let arr = Array(9.3) // RangeError: Invalid array length +</pre> + +<p>任意のデータ型の単一の要素を持つ配列を作成したければ、配列リテラルを使用する方が安全です。あるいは、単一の要素を追加する前に空の配列を作成しましょう。</p> + +<p>ES2015 から単一の要素を持つ配列を生成するために {{jsxref("Array.of")}} 静的メソッドを使用することができます。</p> + +<pre class="brush: js notranslate">let wisenArray = Array.of(9.3) // wisenArray は 1 つの要素 9.3 だけを持つ配列</pre> + +<h3 id="Referring_to_array_elements" name="Referring_to_array_elements">配列要素の参照</h3> + +<p>要素はプロパティでもあるので、<a href="/ja/docs/Web/JavaScript/Reference/Operators/Property_Accessors">プロパティアクセサー</a>を使ってアクセスすることができます。以下の配列を定義するとします。</p> + +<pre class="brush: js notranslate">let myArray = ['Wind', 'Rain', 'Fire'] +</pre> + +<p>要素のインデックスは 0 から始まるので、配列の 1 番目の要素を <code>myArray[0]</code>、2 番目の要素を <code>myArray[1]</code> と呼ぶことができます。</p> + +<div class="note"> +<p><strong>注:</strong> <a href="/ja/docs/Web/JavaScript/Reference/Operators/Property_Accessors">プロパティアクセサー</a>を使用して、オブジェクトのように配列の他のプロパティにアクセスすることもできます。</p> + +<pre class="brush: js notranslate">let arr = ['one', 'two', 'three'] +arr[2] // three +arr['length'] // 3 +</pre> +</div> + +<h3 id="Populating_an_array" name="Populating_an_array">配列へのデータ追加</h3> + +<p>要素に値を割り当てることで配列にデータを追加することができます。例えば、</p> + +<pre class="brush: js notranslate">let emp = [] +emp[0] = 'Casey Jones' +emp[1] = 'Phil Lesh' +emp[2] = 'August West' +</pre> + +<div class="note"> +<p><strong>注:</strong> 上記のコードで配列演算子(角括弧)内に非整数値を指定すると、配列要素ではなく配列を表すオブジェクトのプロパティとして作成されます。</p> + +<pre class="brush: js notranslate">var arr = []; +arr[3.4] = 'Oranges'; +console.log(arr.length); // 0 +console.log(arr.hasOwnProperty(3.4)); // true +</pre> +</div> + +<p>配列を作成するときにも、データを追加することができます。</p> + +<pre class="brush: js notranslate">let myArray = new Array('Hello', myVar, 3.14159) +// または +let myArray = ['Mango', 'Apple', 'Orange'] +</pre> + +<h3 id="Understanding_length" name="Understanding_length">配列の長さの理解</h3> + +<p>実装レベルでは、JavaScript の配列は、配列のインデックスをプロパティ名として使用して、その要素を標準的なオブジェクトのプロパティとして格納します。</p> + +<p><code>length</code> プロパティは特別です。これは常に最終要素のインデックス +1 を返します(次の例では、<code>'Dusty'</code> のインデックスは <code>30</code> なので、<code>cats.length</code> は <code>30 + 1</code> を返します)。</p> + +<p>JavaScript の配列のインデックスは <code>0</code> から始まることを覚えておいてください。これは、<code>length</code> プロパティは配列に格納されている最大のインデックスより <code>1</code> つ多い値になるということです。</p> + +<pre class="brush: js notranslate">var cats = []; +cats[30] = ['Dusty']; +console.log(cats.length); // 31 +</pre> + +<p><code>length</code> プロパティに値を割り当てることもできます。</p> + +<p>格納されているアイテムの数より小さい値を設定すると、配列は切り捨てられます。すなわち、<code>0</code> に設定すると完全に配列を空にします。</p> + +<pre class="brush: js notranslate">let cats = ['Dusty', 'Misty', 'Twiggy']; +console.log(cats.length); // 3 + +cats.length = 2; +console.log(cats); // ログに "Dusty, Misty" - Twiggy は削除される + +cats.length = 0; +console.log(cats); // ログに [ ] 、配列 cats は空になる + +cats.length = 3; +console.log(cats); // ログに [ <3 個の空スロット> ] +</pre> + +<h3 id="Iterating_over_arrays" name="Iterating_over_arrays">配列の反復処理</h3> + +<p>よく行われるのは配列に含まれる値に対し、それぞれの値について、なんらかの処理を行うことです。これを行う一番簡単な方法は次のとおりです。</p> + +<pre class="brush: js notranslate">let colors = ['red', 'green', 'blue']; +for (var i = 0; i < colors.length; i++) { + console.log(colors[i]); +} +</pre> + +<p>配列内の要素がいずれも真偽値としては <code>false</code> に評価されないことがわかっている場合 ― 例えば配列が <a href="/ja/docs/Web/API/Document_Object_Model">DOM</a> ノードのみで構成されている場合などには、例のように、より効率的な表現を使用できます。</p> + +<pre class="brush: js notranslate">let divs = document.getElementsByTagName('div'); +for (var i = 0, div; div = divs[i]; i++) { + /* div に対して何らか処理をする */ +} +</pre> + +<p>この例では、配列の長さのチェックに掛かるオーバーヘッドを回避しています。そしてより便利に使えるように、ループの反復のたびに <code>div</code> 変数に現在の項目を代入するようにしています。</p> + +<p>配列を反復処理する別の方法として {{jsxref("Array.forEach", "forEach()")}} メソッドがあります。</p> + +<pre class="brush: js notranslate">let colors = ['red', 'green', 'blue']; +colors.forEach(function(color) { + console.log(color); +}); +// red +// green +// blue +</pre> + +<p>あるいは、ES2015 のアロー関数式を forEach の引数にしてコードを短縮することもできます。</p> + +<pre class="brush: js notranslate">let colors = ['red', 'green', 'blue']; +colors.forEach(color => console.log(color)); +// red +// green +// blue +</pre> + +<p><code>forEach</code> に渡される関数では、その関数への引数に配列の要素が渡されて、配列内の各項目ごとに 1 回ずつ実行されます。値が割り当てられていない要素は <code>forEach</code> ループで反復されません。</p> + +<p>配列定義の際に省略された要素は、<code>forEach</code> によって反復処理されるときには現れませんが、配列要素に <code>undefined</code> が割り当てられている場合は現れることに注意してください。</p> + +<pre class="brush: js notranslate">let array = ['first', 'second', , 'fourth'] + +array.forEach(function(element) { + console.log(element) +}) +// first +// second +// fourth + +if (array[2] === undefined) { + console.log('array[2] is undefined') // true +} + +array = ['first', 'second', undefined, 'fourth'] + +array.forEach(function(element) { + console.log(element) +}) +// first +// second +// undefined +// fourth +</pre> + +<p>JavaScript では、配列の要素は標準的なオブジェクトプロパティとして保存されるので、{{jsxref("Statements/for...in","for...in")}} ループを使って JavaScript 配列を反復処理するのはお勧めできません。というのも、通常の要素とすべての列挙可能なプロパティが現れるからです。</p> + +<h3 id="Array_methods" name="Array_methods">配列のメソッド</h3> + +<p>{{jsxref("Array")}} オブジェクトには以下のようなメソッドがあります。</p> + +<p>{{jsxref("Array.concat", "concat()")}} は 2 つの配列を結合し、新しい配列を返します。</p> + +<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3') +myArray = myArray.concat('a', 'b', 'c') +// myArray は ["1", "2", "3", "a", "b", "c"] になる +</pre> + +<p>{{jsxref("Array.join", "join(delimiter = ',')")}} は配列のすべての要素を文字列に結合します。</p> + +<pre class="brush: js notranslate">var myArray = new Array('Wind', 'Rain', 'Fire'); +var list = myArray.join(' - '); // list は "Wind - Rain - Fire" になる +</pre> + +<p>{{jsxref("Array.push", "push()")}} は 1 つ以上の要素を配列の最後に追加し、その新しい配列の長さを返します。</p> + +<pre class="brush: js notranslate">var myArray = new Array('1', '2'); +myArray.push('3'); // myArray は ["1", "2", "3"] になる +</pre> + +<p>{{jsxref("Array.pop", "pop()")}} は配列から最後の要素を取り除き、その要素を返します。</p> + +<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3') +let last = myArray.pop() +// myArray は ["1", "2"] に、last は "3" になる +</pre> + +<p>{{jsxref("Array.shift", "shift()")}} は配列から最初の要素を取り除き、その要素を返します。</p> + +<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3') +let first = myArray.shift() +// myArray は ["2", "3"]に、first は "1" になる +</pre> + +<p>{{jsxref("Array.shift", "unshift()")}} は 1 つ以上の要素を配列の先頭に追加し、その新しい配列の長さを返します。</p> + +<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3') +myArray.unshift('4', '5') +// myArray は ["4", "5", "1", "2", "3"] になる +</pre> + +<p>{{jsxref("Array.slice", "slice(start_index, upto_index)")}} は配列の一部を抽出し、新しい配列を返します。</p> + +<pre class="brush: js notranslate">let myArray = new Array('a', 'b', 'c', 'd', 'e') +myArray = myArray.slice(1, 4) // インデックス 1 から始め、インデックス 3 まですべての要素を + // 展開して、[ "b", "c", "d"] を返す +</pre> + +<p>{{jsxref("Array.splice", "splice(index, count_to_remove, addElement1, addElement2, ...)")}} は要素を配列から取り除き、(必要に応じて)置き換えます。</p> + +<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3', '4', '5') +myArray.splice(1, 3, 'a', 'b', 'c', 'd') +// myArray は ["1", "a", "b", "c", "d", "5"] になる +// このコードは、インデックス 1 の要素("2" のある場所)から始まり、 +// 3 つの要素を削除して、そこに後続のすべての要素を挿入します。 +</pre> + +<p>{{jsxref("Array.reverse", "reverse()")}} は配列の中の要素をその場で反転させます。配列の最初の要素が最後に、最後の要素が最初になります。配列への参照を返します。</p> + +<pre class="brush: js notranslate">let myArray = new Array('1', '2', '3') +myArray.reverse() +// 配列要素が入れ替えられ、myArray = ["3", "2", "1"] になる +</pre> + +<p>{{jsxref("Array.sort", "sort()")}} は配列の要素をその場でソートし、その配列の参照を返します。</p> + +<pre class="brush: js notranslate">let myArray = new Array('Wind', 'Rain', 'Fire') +myArray.sort() +// 配列がソートされ、myArray = ["Fire", "Rain", "Wind"] になる +</pre> + +<p><code>sort()</code> は要素を比較する方法を指定するための、コールバック関数を引数として取ることがあります。</p> + +<p>sort メソッドを始めとしコールバック関数を引数として取る以下のメソッドは <strong>{{原語併記("反復メソッド","iterative method")}}</strong> と呼ばれ、何らかの形で配列全体を反復処理します。それぞれが任意で <code>thisObject</code> と呼ばれる第二引数を受け取ります。<code>thisObject</code> が与えられた場合、これがコールバック関数の本体内で <code>this</code> キーワードの値になります。与えられなかった場合は、関数が明示的なオブジェクトコンテキストの外で呼び出された場合と同様に、<code>this</code> はアロー関数がコールバックとして使用された場合にはグローバルオブジェクト({{domxref("window")}})を参照し、通常の関数の場合には <code>undefined</code> になります。</p> + +<p>コールバック関数は、配列の要素 2 つを引数として呼び出されます。</p> + +<p>以下の関数は 2 つの値を比較して、3 つの値のうち 1 つを返します。</p> + +<p>つまり、以下の例は文字列の最後の文字で並べ替えをします。</p> + +<pre class="brush: js notranslate">let sortFn = function(a, b) { + if (a[a.length - 1] < b[b.length - 1]) return -1; + if (a[a.length - 1] > b[b.length - 1]) return 1; + if (a[a.length - 1] == b[b.length - 1]) return 0; +} +myArray.sort(sortFn) +// 配列がソートされ、myArray = ["Wind","Fire","Rain"] になる</pre> + +<ul> + <li>このソートシステムにより <code>a</code> が <code>b</code> より小さいとされた場合、-1(または、任意の負の数)を返します。</li> + <li>このソートシステムにより <code>a</code> が <code>b</code> より大きいとされた場合、1(または、任意の正の数)を返します。</li> + <li><code>a</code> と <code>b</code> が等値と見なされる場合、0 を返します。</li> +</ul> + +<p>{{jsxref("Array.indexOf", "indexOf(searchElement[, fromIndex])")}} は配列から <code>searchElement</code> を検索します。そして、最初に一致した位置のインデックスを返します。</p> + +<pre class="brush: js notranslate">let a = ['a', 'b', 'a', 'b', 'a'] +console.log(a.indexOf('b')) // 1 がログに出力される + +// 最初から最後への検索を試してみる +console.log(a.indexOf('b', 2)) // 3 がログに出力される +console.log(a.indexOf('z')) // 'z' は見つからないので -1 がログに出力される +</pre> + +<p>{{jsxref("Array.lastIndexOf", "lastIndexOf(searchElement[, fromIndex])")}} は <code>indexOf</code> のように動作しますが、最後の要素から開始して前方に検索します。</p> + +<pre class="brush: js notranslate">let a = ['a', 'b', 'c', 'd', 'a', 'b'] +console.log(a.lastIndexOf('b')) // 5 がログに出力される + +// 最後から最初への検索を試してみる +console.log(a.lastIndexOf('b', 4)) // 1 がログに出力される +console.log(a.lastIndexOf('z')) // -1 がログに出力される +</pre> + +<p>{{jsxref("Array.forEach", "forEach(callback[, thisObject])")}} はすべての配列アイテムにコールバック関数 <code>callback</code> を実行し、undefined を返します。</p> + +<pre class="brush: js notranslate">let a = ['a', 'b', 'c'] +a.forEach(function(element) { console.log(element) }) +// 順番にそれぞれのアイテムをログに出力する +</pre> + +<p>{{jsxref("Array.map", "map(callback[, thisObject])")}} はすべての配列アイテムごとにコールバック関数 <code>callback</code> を実行し、戻り値からなる新しい配列を返します。</p> + +<pre class="brush: js notranslate">let a1 = ['a', 'b', 'c'] +let a2 = a1.map(function(item) { return item.toUpperCase() }) +console.log(a2) // ['A', 'B', 'C'] がログに出力される +</pre> + +<p>{{jsxref("Array.filter", "filter(callback[, thisObject])")}} はコールバック関数 <code>callback</code> が true を返すアイテムからなる新しい配列を返します。</p> + +<pre class="brush: js notranslate">let a1 = ['a', 10, 'b', 20, 'c', 30] +let a2 = a1.filter(function(item) { return typeof item === 'number'; }) +console.log(a2) // [10, 20, 30] がログに出力される +</pre> + +<p>{{jsxref("Array.every", "every(callback[, thisObject])")}} はコールバック関数 <code>callback</code> が配列内のすべてのアイテムで true を返す場合に true を返します。</p> + +<pre class="brush: js notranslate">function isNumber(value) { + return typeof value === 'number' +} +let a1 = [1, 2, 3] +console.log(a1.every(isNumber)) // true がログに出力される +let a2 = [1, '2', 3] +console.log(a2.every(isNumber)) // false がログに出力される +</pre> + +<p>{{jsxref("Array.some", "some(callback[, thisObject])")}} はコールバック関数 <code>callback</code> が配列内の少なくとも一つのアイテムで true を返す場合に true を返します。</p> + +<pre class="brush: js notranslate">function isNumber(value) { + return typeof value === 'number' +} +let a1 = [1, 2, 3] +console.log(a1.some(isNumber)) // true がログに出力される +let a2 = [1, '2', 3] +console.log(a2.some(isNumber)) // true がログに出力される +let a3 = ['1', '2', '3'] +console.log(a3.some(isNumber)) // false がログに出力される +</pre> + +<p>{{jsxref("Array.reduce", "reduce(callback[, initialValue])")}} は、配列の各値に対して <code><var>callback</var>(<var>accumulator</var>, <var>currentValue</var>[, <var>currentIndex</var>[, <var>array</var>]])</code> を適用し、項目のリストを一つの値に減らすことを目的としています。<code>reduce</code> 関数は、<code><var>コールバック</var></code>関数によって返された最終的な値を返します。</p> + +<p><code><var>initialValue</var></code> が指定された場合は、<code><var>initialValue</var></code> を第 1 引数の値として、配列の最初の項目の値を第 2 引数の値として<code><var>コールバック</var></code>が呼び出されます。</p> + +<p><code><var>initialValue</var></code> が指定されて<em>いない</em>場合、<code><var>コールバックの</var></code>の最初の 2 つの引数の値は、配列の最初と 2 番目の要素になります。後続の<em>すべての</em>呼び出しで、最初の引数の値は前の呼び出しで<code><var>コールバック</var></code>が返した値になり、2 番目の引数の値は配列の次の値になります。</p> + +<p><code><var>コールバック</var></code>が処理対象の項目のインデックスにアクセスする必要がある場合は、配列全体にアクセスするときに、オプションの引数として利用できます。</p> + +<pre class="brush: js notranslate">let a = [10, 20, 30] +let total = a.reduce(function(accumulator, currentValue) { return accumulator + currentValue }, 0) +console.log(total) // 60 がログに出力される +</pre> + +<p>{{jsxref("Array.reduceRight", "reduceRight(callback[, initialValue])")}} は <code>reduce()</code> のように機能します。しかし最後の要素から適用を開始します。</p> + +<p><code>reduce</code> と <code>reduceRight</code> もある意味では配列の反復メソッドです。要素列を単一の値に還元するために、再帰的に 2 つの値を組み合わせるアルゴリズムにこれらのメソッドを使用してください。</p> + +<h3 id="Multi-dimensional_arrays" name="Multi-dimensional_arrays">多次元配列</h3> + +<p>配列をネストすることができます、つまり配列要素として配列を含めることができることを意味します。JavaScript の配列の特徴を活かして、多次元配列を生成できます。</p> + +<p>以下のコードでは 2次元配列を作成しています。</p> + +<pre class="brush: js notranslate">let a = new Array(4) +for (let i = 0; i < 4; i++) { + a[i] = new Array(4) + for (let j = 0; j < 4; j++) { + a[i][j] = '[' + i + ', ' + j + ']' + } +} +</pre> + +<p>この例では、次のテーブル行を持つ配列を作成しています。</p> + +<pre class="notranslate">Row 0: [0, 0] [0, 1] [0, 2] [0, 3] +Row 1: [1, 0] [1, 1] [1, 2] [1, 3] +Row 2: [2, 0] [2, 1] [2, 2] [2, 3] +Row 3: [3, 0] [3, 1] [3, 2] [3, 3] +</pre> + +<h3 id="Using_arrays_to_store_other_properties" name="Using_arrays_to_store_other_properties">配列を使用して他のプロパティを格納する</h3> + +<p>配列は、オブジェクトのように関連する情報を格納するために使用することもできます。</p> + +<pre class="brush: js notranslate"><code>const arr = [1, 2, 3]; +arr.property = "value"; +console.log(arr.property); // "value" がログに出力される</code> +</pre> + +<h3 id="Arrays_and_regular_expressions" name="Arrays_and_regular_expressions">配列と正規表現</h3> + +<p>配列が正規表現と文字列との間の一致結果である場合、その配列は一致についての情報を提供するプロパティと要素を返します。{{jsxref("Global_Objects/RegExp/exec","RegExp.exec()")}}、{{jsxref("Global_Objects/String/match","String.match()")}}、{{jsxref("Global_Objects/String/split","String.split()")}} による戻り値がこうした配列となります。正規表現とともに配列を使用する際の情報については、当ガイドの<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions">正規表現</a>の章をご覧ください。</p> + +<h3 id="Working_with_array-like_objects" name="Working_with_array-like_objects">配列用のオブジェクトを利用する</h3> + +<p>{{domxref("document.getElementsByTagName()")}} によって返される {{domxref("NodeList")}} や、関数本体内で利用できる {{jsxref("Functions/arguments","arguments")}} オブジェクトのように、表面上は配列のようにふるまう JavaScript オブジェクトがありますが、これらはメソッドすべてを共有してはいません。例えば、<code>arguments</code> オブジェクトには {{jsxref("Global_Objects/Function/length","length")}} 属性がありますが、{{jsxref("Array.forEach", "forEach()")}} メソッドは実装されていません。</p> + +<p>配列状のオブジェクトに対して配列メソッドを直接呼び出すことはできません。</p> + +<pre class="brush: js example-bad notranslate"><code>function printArguments() { + arguments.forEach(function(item) { // <span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="objectBox-stackTrace reps-custom-format">TypeError: <span class="objectBox objectBox-string">arguments.forEach is not a function</span></span></span></span></span> + console.log(item); + }); +}</code> +</pre> + +<p>これを行うには、{{jsxref("Global_Objects/Function/call","Function.prototype.call()")}} を使って間接的に呼び出します。</p> + +<pre class="brush: js example-good notranslate"><code>function printArguments() { + Array.prototype.forEach.call(arguments, function(item) { + console.log(item); + }); +}</code> +</pre> + +<p>配列のプロトタイプメソッドは、配列と同様の方法で文字に逐次アクセスできるため、文字列にも使用できます。</p> + +<pre class="brush: js notranslate">Array.prototype.forEach.call('a string', function(chr) { + console.log(chr) +}) +</pre> + +<h2 id="Typed_Arrays" name="Typed_Arrays">型付き配列</h2> + +<p><a href="/ja/docs/Web/JavaScript/Typed_arrays">JavaScript の型付き配列</a>は配列用のオブジェクトで、未加工のバイナリーデータにアクセスする仕組みをもたらします。ご存知のように、{{jsxref("Array")}} オブジェクトは動的に拡大、縮小し、JavaScript におけるいかなる値でも保持することができます。JavaScript エンジンは最適化を行うため、これらの配列は高速に機能します。しかし、オーディオやビデオ操作といった機能が追加され、<a href="/ja/docs/WebSockets">WebSocket</a> を使い未加工のデータにアクセスするなど、Web アプリケーションはさらにパワフルなものとなってきました、そのため JavaScript コードが型付き配列内の未加工バイナリーデータを手早く簡単に操作できれば有益である場合がよくある、ということが明らかになってきました。</p> + +<h3 id="Buffers_and_views_typed_array_architecture" name="Buffers_and_views_typed_array_architecture">バッファとビュー : 型付き配列のアーキテクチャ</h3> + +<p>最大の柔軟性と効率性を達成するため、JavaScript 型付き配列の実装を<strong>バッファ</strong>と<strong>ビュー</strong>に分離しました。バッファ({{jsxref("ArrayBuffer")}} オブジェクトによる実装)はデータのかたまりを表すオブジェクトです。語るほどのフォーマットはなく、データの中身にアクセスするためのメカニズムを提供しません。バッファに含まれるメモリーにアクセスするには、ビューを使用する必要があります。ビューはデータを実際の型付き配列に変換する<strong>コンテキスト</strong> — つまり、データ型、開始位置のオフセット、要素数 — を提供します。</p> + +<p><img alt="Typed arrays in an ArrayBuffer" src="https://mdn.mozillademos.org/files/8629/typed_arrays.png" style="height: 278px; width: 666px;"></p> + +<h3 id="ArrayBuffer" name="ArrayBuffer">ArrayBuffer</h3> + +<p>{{jsxref("ArrayBuffer")}} は汎用的な固定長のバイナリーデータバッファを表すために使用されるデータ型です。<code>ArrayBuffer</code> の内容は直接操作できません。かわりに、型付き配列ビューか特定のフォーマットでバッファを表す {{jsxref("DataView")}} を生成し、それらをバッファの内容の読み書きに使用します。</p> + +<h3 id="Typed_array_views" name="Typed_array_views">型付き配列ビュー</h3> + +<p>型付き配列ビューは自己記述的な名前を持っていて、そのすべてが <code>Int8</code>, <code>Uint32</code>, <code>Float64</code> などといったよく見られる数値型用のビューを提供しています。<code>Uint8ClampedArray</code> という 1 つ特別な型付き配列ビューがあります。これは、0〜255 の範囲に値を固定します。これは、例えば、<a href="/ja/en-US/docs/Web/API/ImageData">Canvas のデータ処理</a>に便利です。</p> + +<table class="standard-table"> + <thead> + <tr> + <th class="header" scope="col">型</th> + <th class="header" scope="col">値の範囲</th> + <th class="header" scope="col">サイズ (バイト数)</th> + <th class="header" scope="col">説明</th> + <th class="header" scope="col">Web IDL 型</th> + <th class="header" scope="col">同等の C 型</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Int8Array")}}</td> + <td><code>-128</code> から <code>127</code></td> + <td>1</td> + <td>8 ビット 2 の補数方式の符号付き整数値</td> + <td><code>byte</code></td> + <td><code>int8_t</code></td> + </tr> + <tr> + <td>{{jsxref("Uint8Array")}}</td> + <td><code>0</code> から <code>255</code></td> + <td>1</td> + <td>8 ビット 符号なし整数値</td> + <td><code>octet</code></td> + <td><code>uint8_t</code></td> + </tr> + <tr> + <td>{{jsxref("Uint8ClampedArray")}}</td> + <td><code>0</code> から <code>255</code></td> + <td>1</td> + <td>8 ビット 符号なし整数値 (切り詰め)</td> + <td><code>octet</code></td> + <td><code>uint8_t</code></td> + </tr> + <tr> + <td>{{jsxref("Int16Array")}}</td> + <td><code>-32768</code> から <code>32767</code></td> + <td>2</td> + <td>16 ビット 2 の補数方式の符号付き整数値</td> + <td><code>short</code></td> + <td><code>int16_t</code></td> + </tr> + <tr> + <td>{{jsxref("Uint16Array")}}</td> + <td><code>0</code> から <code>65535</code></td> + <td>2</td> + <td>16 ビット 符号なし整数値</td> + <td><code>unsigned short</code></td> + <td><code>uint16_t</code></td> + </tr> + <tr> + <td>{{jsxref("Int32Array")}}</td> + <td><code>-2147483648</code> から <code>2147483647</code></td> + <td>4</td> + <td>32 ビット 2 の補数方式の符号付き整数値</td> + <td><code>long</code></td> + <td><code>int32_t</code></td> + </tr> + <tr> + <td>{{jsxref("Uint32Array")}}</td> + <td><code>0</code> から <code>4294967295</code></td> + <td>4</td> + <td>32 ビット 符号なし整数値</td> + <td><code>unsigned long</code></td> + <td><code>uint32_t</code></td> + </tr> + <tr> + <td>{{jsxref("Float32Array")}}</td> + <td><code>1.2</code><span>×</span><code>10<sup>-38</sup></code> から <code>3.4</code><span>×</span><code>10<sup>38</sup></code></td> + <td>4</td> + <td>32 ビット IEEE 浮動小数点数 (7 桁の有効数字 例:<code>1.1234567</code>)</td> + <td><code>unrestricted float</code></td> + <td><code>float</code></td> + </tr> + <tr> + <td>{{jsxref("Float64Array")}}</td> + <td><code>5.0</code><span>×</span><code>10<sup>-324</sup></code> から <code>1.8</code><span>×</span><code>10<sup>308</sup></code></td> + <td>8</td> + <td>64 ビット IEEE 浮動小数点数 (16 桁の有効数字 例:<code>1.123...15</code>)</td> + <td><code>unrestricted double</code></td> + <td><code>double</code></td> + </tr> + <tr> + <td>{{jsxref("BigInt64Array")}}</td> + <td><code>-2<sup>63</sup></code> から <code>2<sup>63</sup>-1</code></td> + <td>8</td> + <td>64 ビット 2 の補数方式の符号付き整数値</td> + <td><code>bigint</code></td> + <td><code>int64_t (signed long long)</code></td> + </tr> + <tr> + <td>{{jsxref("BigUint64Array")}}</td> + <td><code>0</code> から <code>2<sup>64</sup>-1</code></td> + <td>8</td> + <td>64 ビット 符号なし整数値</td> + <td><code>bigint</code></td> + <td><code>uint64_t (unsigned long long)</code></td> + </tr> + </tbody> +</table> + +<p>詳細については、<a href="/docs/Web/JavaScript/Typed_arrays">JavaScript 型付き配列</a>と様々な {{jsxref("TypedArray")}} オブジェクトに関するリファレンスをご覧ください。</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}</p> diff --git a/files/ja/web/javascript/guide/introduction/index.html b/files/ja/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..189df7a18b --- /dev/null +++ b/files/ja/web/javascript/guide/introduction/index.html @@ -0,0 +1,160 @@ +--- +title: 入門編 +slug: Web/JavaScript/Guide/Introduction +tags: + - Beginner + - Guide + - Introduction + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Introduction +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}</div> + +<p class="summary">本章では JavaScript について紹介し、その基本的なコンセプトについて説明します。</p> + +<h2 id="What_you_should_already_know" name="What_you_should_already_know">事前に知っておくべきこと</h2> + +<p>このガイドは、以下の基礎的な予備知識を持っていることを前提としています:</p> + +<ul> + <li>インターネットと World Wide Web ({{Glossary("World_Wide_Web", "WWW")}}) についての一般的な理解。</li> + <li>HyperText Markup Language ({{Glossary("HTML")}}) についての実用的な知識。</li> + <li>プログラミングの経験。プログラミングが初めての方は、<a href="/docs/Web/JavaScript">JavaScript</a> についてのメインページにあるチュートリアルをお試しください。</li> +</ul> + +<h2 id="Where_to_find_JavaScript_information" name="Where_to_find_JavaScript_information">JavaScript の情報源</h2> + +<p>MDN には以下の JavaScript 関連ドキュメントがあります:</p> + +<ul> + <li>「<a href="/ja/docs/Learn">Web 開発を学ぶ</a>」では初心者に向けた情報を提供し、プログラミングとインターネットの基本的なコンセプトを提供しています。</li> + <li>「<a href="/docs/Web/JavaScript/Guide">JavaScript ガイド</a>」(このガイド) では、JavaScript 言語とその対象に関する概要を提供しています。</li> + <li>「<a href="/docs/Web/JavaScript/Reference">JavaScript リファレンス</a>」は、JavaScript の詳細なリファレンスマニュアルを提供しています。</li> +</ul> + +<p>JavaScript を初めて学ぶ方は、<a href="/Learn">学習エリア</a>、および <a href="/docs/Web/JavaScript/Guide">JavaScript ガイド</a>の記事から始めてください。基礎をしっかり学んだら、<a href="/docs/Web/JavaScript/Reference">JavaScript リファレンス</a>を利用して、個別のオブジェクトや文についての詳細を得てください。</p> + +<h2 id="What_is_JavaScript" name="What_is_JavaScript">JavaScript とは?</h2> + +<p>JavaScript は、クロスプラットフォームで動作するオブジェクト指向のスクリプト言語で、ウェブページをインタラクティブにするために使用されます (例えば、複雑なアニメーション、押下可能なボタン、ポップアップメニューなどを設けることです) 。Node.js のような より高度なサーバー側のバージョンの JavaScript もあり、ファイルをダウンロードするだけでなく (複数のコンピューター間でのリアルタイムコラボレーションなど) 、ウェブサイトに多くの機能を追加することができます。ホスト環境 (例えばウェブブラウザー) 内では、JavaScript とその環境のオブジェクトが結びつけられ、プログラム制御が可能になっています。</p> + +<p>JavaScript には、<code>Array</code>、<code>Date</code>、そして <code>Math</code> といったオブジェクトからなる基本的なライブラリ、そして演算子、制御構造、文といったプログラミング言語の要素からなる主要な機能が含まれています。JavaScript のコア機能は、追加のオブジェクトを補うことで、様々な目的に拡張することができます。例えば以下のようなものです:</p> + +<ul> + <li><em>クライアントサイド JavaScript</em> は、ブラウザーとその<em>ドキュメントオブジェクトモデル</em> (DOM) を制御するオブジェクトを提供することにより、コア言語を拡張します。例えば、クライアントサイドでの拡張により、アプリケーションが HTML フォーム上に要素を配置したり、マウスクリック、フォームへの入力、ページ移動といったユーザーイベントに応答できるようにします。</li> + <li><em>サーバーサイド JavaScript</em> は、JavaScript を使ったサーバーの稼働に関連するオブジェクトを提供することにより、コア言語を拡張します。例えば、サーバーサイドでの拡張により、アプリケーションがデータベースとデータをやり取りしたり、アプリケーション内のある呼び出しから別の呼び出しまでの間を情報が連続性を保ったまま受け取られるようにしたり、あるいはサーバー上のファイルを操作できるようにします。</li> +</ul> + +<p>これはつまり、ブラウザー内で JavaScript がウェブページ (DOM) の見た目を変更できるということです。同様に、サーバー上の Node.js の JavaScript は、ブラウザー内に記述されたコードからのカスタム要求に応答できます。</p> + +<h2 id="JavaScript_and_Java" name="JavaScript_and_Java">JavaScript と Java</h2> + +<p>JavaScript と Java はいくつかの点では似ていますが、その他の点では全くの別物です。JavaScript 言語は Java と共通点がありますが、Java のような静的型付けと強い型検査を持っていません。LiveScript から JavaScript へ改名する理由ともなった、Java が持つ多くの式構文、命名規則と基本的な制御フローを JavaScript は踏襲しています。</p> + +<p>宣言によって作られたクラスから構成される Java のコンパイル時システムとは対照的に、JavaScript は、数値や真偽値、文字列を表す少数のデータ型をベースにしたランタイムシステムをサポートしています。JavaScript は、より一般的であるクラスベースのオブジェクトモデルの代わりに、プロトタイプベースのオブジェクトモデルを持っています。プロトタイプベースモデルは動的な継承をもたらします、それはつまり、様々なオブジェクトから継承できるということです。また JavaScript は、特殊な宣言型を必要としない関数をサポートしています。関数はオブジェクトのプロパティに設定することができ、弱い型付けのメソッドとして実行することができます。</p> + +<p>JavaScript は Java に比べて非常に自由な形式を持つ言語です。変数、クラス、メソッドをあまねく宣言する必要はありません。メソッドが public か private か、あるいは protected かどうかを気に掛けることも、インターフェイスを実装する必要もありません。変数、引数、そして型を返す関数は厳密に型付けされていません。</p> + +<p>Java は高速実行と型安全のために設計されたクラスベースのプログラミング言語です。型安全というのは、例えば Java の整数値はオブジェクトの参照値として型変換することはできず {{訳注("Java のデータ型は、数値や文字列などのデータのみを表すプリミティブ型とクラス定義されたオブジェクト型 (参照型とも呼ばれる) の 2 つに分かれており、プリミティブ型のデータをオブジェクトから参照する場合はラッパークラスを使い、そのデータを適切なオブジェクト型に明示的に変換する必要がある")}}、またメモリー環境を破壊しようとする Java バイトコードからはプライベートメモリーにアクセスできないようになっているということです。Java のクラス継承と強い型付けは一般的に密結合されたオブジェクト階層を必要とします。こうした前提条件によって Java プログラミングは JavaScript プログラミングに比べ複雑なものとなります。</p> + +<p>それとは対照的に、JavaScript は HyperTalk や dBASE といった一連の小規模で動的型付けを持つ言語の精神を受け継いでいます。これらのスクリプト言語が持っている、より簡素な構文、専門化されたビルトイン関数、そして最低限の条件のみを必要とするオブジェクト作成のおかげで、より広い人々にプログラミングという道具をもたらしてくれます。</p> + +<table class="standard-table"> + <caption>JavaScript と Java との比較</caption> + <thead> + <tr> + <th scope="col">JavaScript</th> + <th scope="col">Java</th> + </tr> + </thead> + <tbody> + <tr> + <td>オブジェクト指向言語。オブジェクトのデータ型に区別はない。継承はプロトタイプベースの機構を通して行われ、プロパティとメソッドはどんなオブジェクトにも動的に追加できる。</td> + <td>クラスベース言語。オブジェクトはクラスとそのクラス階層によって継承されたインスタンスとに分かれている。クラスとインスタンスは動的にプロパティやメソッドを追加することができない。</td> + </tr> + <tr> + <td>変数のデータ型は宣言が不要(動的型付け、弱い型付け)。</td> + <td>変数のデータ型は宣言が必須(静的型付け、強い型付け)。</td> + </tr> + <tr> + <td>ハードディスクには自動的に書き込みできない。</td> + <td>ハードディスクには自動的に書き込みできる。</td> + </tr> + </tbody> +</table> + +<p>JavaScript と Java との違いについてのさらに詳しい情報は、<a href="/docs/Web/JavaScript/Guide/Details_of_the_Object_Model">オブジェクトモデルの詳細</a>の章をご覧ください。</p> + +<h2 id="JavaScript_and_the_ECMAScript_Specification" name="JavaScript_and_the_ECMAScript_Specification">JavaScript と ECMAScript 仕様</h2> + +<p>JavaScript は国際的なプログラミング言語を提供できるように <a class="external" href="https://www.ecma-international.org/">Ecma International</a> によって標準化されています (ECMA は、以前は European Computer Manufacturers Association の頭文字をとったものでした)。この標準化された JavaScript のバージョンは ECMAScript と呼ばれ、この標準をサポートするアプリケーションはすべて同じ動作になります。企業は、JavaScript の実装開発にこのオープンな標準言語を利用できます。ECMAScript 標準は、ECMA-262 仕様に文書化されています。JavaScript バージョンと ECMAScript 標準化の各版との違いについて知りたい場合は <a href="/docs/Web/JavaScript/New_in_JavaScript">JavaScript の新機能</a>をご覧ください。</p> + +<p>ECMA-262 標準は、<a class="external" href="https://www.iso.org/home.html">ISO</a>(International Organization for Standardization、国際標準化機構)により ISO-16262 としても承認されています。また仕様書は、<a class="external" href="https://www.ecma-international.org/publications/standards/Ecma-262.htm">Ecma International のウェブサイト</a>でも確認できます。ECMAScript 仕様には、<a class="external" href="https://www.w3.org/">World Wide Web Consortium (W3C)</a> によって標準化されているドキュメントオブジェクトモデル (DOM) が記載されていません。DOM はスクリプトから利用できる HTML ドキュメントのオブジェクトを定義しています。JavaScript でプログラミングする際に使われる様々な技術のさらに詳しい情報は、<a href="/docs/Web/JavaScript/JavaScript_technologies_overview">JavaScript 技術概説</a>の記事を参考にしてください。</p> + +<h3 id="JavaScript_Documentation_versus_the_ECMAScript_Specification" name="JavaScript_Documentation_versus_the_ECMAScript_Specification">JavaScript ドキュメント vs ECMAScript 仕様書</h3> + +<p>ECMAScript 仕様は ECMAScript の実装要件の集合体です。これは ECMAScript 実装やブラウザー描画エンジン (Firefox の SpiderMonkey、あるいは Chrome の V8 など) に対し、標準に準拠した言語機能を実装したい場合には便利です。</p> + +<p>ECMAScript の文書はスクリプトプログラマを支援するためのものではありません。スクリプトの記述についての情報を知りたければ JavaScript のドキュメントを使いましょう。</p> + +<p>ECMAScript 仕様書は、JavaScript プログラマにあまり馴染みのない専門用語と文法で書かれています。この言語を解説したものと ECMAScript とは異なるところがあるかもしれませんが、この言語自体は同じものです。JavaScript は、ECMAScript 仕様書で描かれた機能をすべてサポートしています。</p> + +<p>JavaScript のドキュメントは、JavaScript プログラマに適した形で言語の特徴について記述しています。</p> + +<h2 id="Getting_started_with_JavaScript" name="Getting_started_with_JavaScript">JavaScript を始めよう</h2> + +<p>JavaScript を始めるのは簡単です。必要なものは、最新のウェブブラウザーだけです。このガイドでは最新の Firefox でのみ利用できる JavaScript の機能をいくつか使用するので、最新の Firefox を使用することをお勧めします。</p> + +<p>Firefox に組み込まれている<em>ウェブコンソール</em>ツールは、JavaScript を試すのに役立ちます。シングルライン入力モードとマルチライン入力モードの 2 つのモードで使用できます。</p> + +<h3 id="Single-line_input_in_the_Web_Console" name="Single-line_input_in_the_Web_Console">ウェブコンソールでの単一行入力</h3> + +<p><a href="/ja/docs/Tools/Web_Console">ウェブコンソール</a>には、現在読み込まれているウェブページの情報が表示されるほか、現在のページで JavaScript 式を実行するために使用できる JavaScript インタープリターも含まれています。</p> + +<p>ウェブコンソールを開くには(Windows および Linux では <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>I</kbd>、Mac では <kbd>Cmd</kbd>-<kbd>Option</kbd>-<kbd>K</kbd>)、Firefox の<strong>ツール</strong>メニューを開き、<strong>ウェブ開発 ▶ ウェブコンソール</strong>を選択します。</p> + +<p>ブラウザーウィンドウの下部にウェブコンソールが表示されます。コンソールの下部に沿って、JavaScript を入力するための入力行があり、出力は上のパネルに表示されます。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/16569/2019-04-04_00-15-29.png" style="display: block; height: 1824px; margin-left: auto; margin-right: auto; width: 2784px;"></p> + +<p>コンソールは <code>eval</code> と全く同じように動作し、最後に入力された式が返されます。これはコンソールに何かが入力されるたびに、<code>console.log</code> で囲まれた <code>eval</code> で評価されていると想像できます。</p> + +<pre class="brush: js notranslate">function greetMe(yourName) { + alert('Hello ' + yourName); +} +<code>console.log(eval('3 + 5'));</code> +</pre> + +<h3 id="Multi-line_input_in_the_Web_Console" name="Multi-line_input_in_the_Web_Console">ウェブコンソールでの複数行入力</h3> + +<p>ウェブコンソールの単一行入力モードは、JavaScript の式を素早くテストするのには最適ですが、複数行を実行するには向いていません。より複雑な JavaScript の場合は、<a href="/ja/docs/Tools/Web_Console/The_command_line_interpreter#Multi-line_mode">複数行の入力モード</a>を使用できます。</p> + +<h3 id="Hello_world" name="Hello_world">Hello world</h3> + +<p>JavaScript を書き始めるあたり、ウェブコンソールを複数行モードで開いて、初めての JavaScript コード "Hello world" を書いてみましょう。</p> + +<pre class="brush: js notranslate">(function(){ + "use strict"; + /* コードの開始 */ + function greetMe(yourName) { + alert('Hello ' + yourName); + } + + greetMe('World'); + /* コードの終了 */ +})();</pre> + +<p><kbd>Cmd</kbd>+<kbd>Enter</kbd> または <kbd>Ctrl</kbd>+<kbd>Enter</kbd> を押して(または<strong>実行ボタン</strong>をクリック)、結果を見てみましょう!</p> + +<p>このガイドの以降のページでは、より複雑なアプリケーションを作成できるように、JavaScript の構文と言語の特徴を紹介します。</p> + +<p>ですが、しばらくの間、常にあなたのコードの先頭に <code>(function(){"use strict";</code> を、コードの最後に <code>})();</code> を記述することを忘れないでください。あとで<a href="/ja/docs/Glossary/IIFE">これらの意味</a>を学びますが、今のところは次のように捉えておいてください。</p> + +<ol> + <li>パフォーマンスを大幅に向上させる。</li> + <li>初心者をつまづかせる、JavaScript の愚かなセマンティクスを避ける。</li> + <li>コンソールで実行されたコードスニペットが相互に影響することを防止する。(たとえば、あるコンソールの実行で作成されたものを別のコンソールの実行に使用するなど) </li> +</ol> + +<p>{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}</p> diff --git a/files/ja/web/javascript/guide/iterators_and_generators/index.html b/files/ja/web/javascript/guide/iterators_and_generators/index.html new file mode 100644 index 0000000000..685898d31f --- /dev/null +++ b/files/ja/web/javascript/guide/iterators_and_generators/index.html @@ -0,0 +1,242 @@ +--- +title: イテレーターとジェネレーター +slug: Web/JavaScript/Guide/Iterators_and_Generators +tags: + - Guide + - Intermediate + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Iterators_and_Generators +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Using_promises", "Web/JavaScript/Guide/Meta_programming")}}</div> + +<div class="summary"> +<p>コレクション内の各アイテムに対する処理は非常に一般的な操作です。JavaScript では簡単な {{jsxref("Statements/for","for")}} ループから {{jsxref("Global_Objects/Array/map","map()")}}、{{jsxref("Global_Objects/Array/filter","filter()")}} にいたるまで、コレクションに対する反復処理の複数の方法を提供します。</p> + +<p>イテレーターとジェネレーターは、コア言語の内部に反復処理が直接的に取り入れられており、{{jsxref("Statements/for...of","for...of")}} ループの動作を簡単にカスタマイズできる仕組みをもたらします。</p> +</div> + +<p>詳細についてはこちらもご覧ください:</p> + +<ul> + <li><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Iteration_protocols">Iteration protocols</a></li> + <li>{{jsxref("Statements/for...of","for...of")}}</li> + <li>{{jsxref("Statements/function*","function*")}} と {{jsxref("Generator","ジェネレーター","","true")}}</li> + <li>{{jsxref("Operators/yield","yield")}} と {{jsxref("Operators/yield*","yield*")}}</li> +</ul> + +<h2 id="Iterators" name="Iterators">イテレーター</h2> + +<p>JavaScript では、<strong>イテレーター</strong>はシーケンスおよび潜在的には終了時の戻り値を定義するオブジェクトです。</p> + +<p>より具体的に言うと、イテレーターは、次の 2 つのプロパティを持つオブジェクトを返す <code style="font-style: normal;">next()</code> メソッドを持つことによってイテレータープロトコルを実装するオブジェクトです。</p> + +<dl> + <dt><code><var>value</var></code></dt> + <dd>反復シーケンスの次の値</dd> + <dt><code><var>done</var></code></dt> + <dd>シーケンスの最後の値が既に消費されている場合に <code>true</code> となります。<code><var>done</var></code> と並んで <code><var>value</var></code> が存在する場合、それがイテレーターの戻り値となります。</dd> +</dl> + +<p>イテレーターオブジェクトが作成されると、<code>next()</code> を繰り返し呼び出すことによって、明示的に反復することができます。イテレーターを反復することを、イテレーターを消費すると言います。一般的に 1 回しか実行できないためです。終了値が返された後、さらに <code>next()</code> を呼び出しても、単に <code>{done: true}</code> を返し続けます。</p> + +<p>Javascript で最も一般的なイテレーターは配列イテレーターで、配列の各値を順番に返します。</p> + +<p>すべてのイテレーターを配列として表現できるとは想像するのは容易ですが、これは真実ではありません。配列は完全に割り当てなければなりませんが、イテレーターは必要なだけで消費されるため、0 から Infinity までの整数の範囲など、無限のサイズのシーケンスを表現できます。</p> + +<p>ここでは、それを行うことができる例を示します。<code>start</code> (包括) から <code>end</code> (排他) までの一連の整数を定義する単純な範囲のイテレーターの作成を可能にします。最終的な戻り値は、作成したシーケンスのサイズあり、変数 <code><var>iterationCount</var></code> で追跡されます。</p> + +<pre class="brush: js notranslate">function makeRangeIterator(<var>start</var> = 0, <var>end</var> = Infinity, <var>step</var> = 1) { + let nextIndex = start; + let iterationCount = 0; + + const rangeIterator = { + next: function() { + let result; + if (nextIndex < end) { + result = { value: nextIndex, done: false } + nextIndex += step; + iterationCount++; + return result; + } + return { value: iterationCount, done: true } + } + }; + return rangeIterator; +} +</pre> + +<p>このイテレーターを使えば、次のようになります:</p> + +<pre class="brush: js notranslate">const it = makeRangeIterator(1, 10, 2); + +let result = it.next(); +while (!result.done) { + console.log(result.value); // 1 3 5 7 9 + result = it.next(); +} + +console.log("Iterated over sequence of size: ", result.value); // [5 numbers returned, that took interval in between: 0 to 10] +</pre> + +<div class="note"> +<p><strong>メモ:</strong> 特定のオブジェクトがイテレーターであるかどうかは考えても知ることはできません。それが必要な場合は、<a href="#Iterables">反復可能オブジェクト</a>を使用してください。</p> +</div> + +<h2 id="Generators" name="Generators">ジェネレーター関数</h2> + +<p>カスタムイテレーターは便利なツールですが、その作成には内部状態を明示的に維持する必要があるため、慎重なプログラミングが必要です。ジェネレーター関数は強力な代替手段を提供します。実行が連続していない単一の関数を記述することによって反復アルゴリズムを定義できます。ジェネレーター関数は、{{jsxref("Statements/function*","function*")}} 構文を使用して記述されます。</p> + +<p>最初に呼び出されると、ジェネレーター関数はコードを実行せず、ジェネレーターと呼ばれるある種のイテレーターを返します。ジェネレーターの <strong>next</strong> メソッドを呼び出すことによって値が消費されると、ジェネレーター関数は <strong>yield</strong> キーワードを検出するまで実行します。</p> + +<p>この関数は、必要な回数だけ呼び出すことができ、毎回新しいジェネレーターを返しますが、各ジェネレーターは 1 回のみ反復することができます。</p> + +<p>上の例に適用してみましょう。このコードの動作は同じですが、実装は書くのも読むのもはるかに容易になります。</p> + +<pre class="brush: js notranslate">function* makeRangeIterator(<var>start</var> = 0, <var>end</var> = 100, <var>step</var> = 1) { + let iterationCount = 0; + for (let i = start; i < end; i += step) { + iterationCount++; + yield i; + } + return iterationCount; +}</pre> + +<h2 id="Iterables" name="Iterables">反復可能オブジェクト</h2> + +<p>オブジェクトは、{{jsxref("Statements/for...of", "for...of")}} 構文でループされる値など反復動作を定義する場合、<strong>反復可能オブジェクト</strong>です。{{jsxref("Array")}} や {{jsxref("Map")}} のような組み込み型の中にはデフォルトの反復動作を持つものがありますが、他の型 ({{jsxref("Object")}} など) は持っていません。</p> + +<p><strong>反復可能オブジェクト</strong>にするには、オブジェクトは <strong>@@iterator</strong> メソッドを実装する必要があります。つまり、オブジェクト (またはプロトタイプチェーン上のオブジェクトのうちの 1 つ) に {{jsxref("Symbol.iterator")}} キーを持つプロパティが必要です 。</p> + +<p>反復可能オブジェクトは 1 回だけでも 2 回以上でも反復することができます。どちらが当てはまるかは、プログラマに任されています。</p> + +<p>一度しか反復することができない反復可能オブジェクト (例えば、ジェネレーター) は、通常 <strong>@@iterator</strong> メソッドから <strong>this</strong> を返します。何度も繰り返し可能なものは、<strong>@@iterator</strong> の各呼び出しで新しいイテレーターを返す必要があります。</p> + +<pre class="brush: js notranslate">function* makeIterator() { + yield 1; + yield 2; +} + +const <var>it</var> = makeIterator(); + +for (const <var>itItem</var> of <var>it</var>) { + console.log(<var>itItem</var>); +} + +console.log(<var>it</var>[Symbol.iterator]() === <var>it</var>) // true; + +// This example show us generator(iterator) is iterable object, +// which has the @@iterator method return the <var>it</var> (itself), +// and consequently, the <var>it</var> object can iterate only _once_. + + +// If we change <var>it</var>'s @@iterator method to a function/generator +// which returns a new iterator/generator object, (<var>it</var>) +// can iterate many times + +<var>it</var>[Symbol.iterator] = function* () { + yield 2; + yield 1; +}; +</pre> + +<h3 id="User-defined_iterables" name="User-defined_iterables">ユーザー定義の反復可能オブジェクト</h3> + +<p>以下のようにして反復可能オブジェクトを自作することができます:</p> + +<pre class="brush: js notranslate">var myIterable = { + *[Symbol.iterator]() { + yield 1; + yield 2; + yield 3; + } +} + +for (let value of myIterable) { + console.log(value); +} +// 1 +// 2 +// 3 + +or + +[...myIterable]; // [1, 2, 3] +</pre> + +<h3 id="Built-in_iterables" name="Built-in_iterables">組み込み反復可能オブジェクト</h3> + +<p>{{jsxref("String")}}、{{jsxref("Array")}}、{{jsxref("TypedArray")}}、{{jsxref("Map")}}、{{jsxref("Set")}} はすべて組み込み反復可能オブジェクトです。これらのオブジェクトはすべて、そのプロトタイプオブジェクトに {{jsxref("Symbol.iterator")}} メソッドを備えているためです。</p> + +<h3 id="Syntaxes_expecting_iterables" name="Syntaxes_expecting_iterables">反復可能オブジェクトが必要な構文</h3> + +<p>{{jsxref("Statements/for...of","for-of")}} ループ、{{jsxref("Operators/yield*","yield*")}} などの文や式は、反復可能オブジェクトを必要とします。</p> + +<pre class="brush: js notranslate">for (let value of ['a', 'b', 'c']) { + console.log(value); +} +// "a" +// "b" +// "c" + +[...'abc']; +// ["a", "b", "c"] + +function* gen() { + yield* ['a', 'b', 'c']; +} + +gen().next(); +// { value: "a", done: false } + +[a, b, c] = new Set(['a', 'b', 'c']); +a; +// "a" + +</pre> + +<h2 id="Advanced_generators" name="Advanced_generators">高度なジェネレーター</h2> + +<p>ジェネレーターは要求に応じて yield 文により生成される値を計算しており、多くの計算が必要な一連のデータを効率的に表現したり、前出のとおり無限のシーケンスを表現したりすることを可能にします。</p> + +<p>ジェネレーターの内部状態を変更するのための値を {{jsxref("Global_Objects/Generator/next","next()")}} メソッドで受け入れることもできます。<code>next()</code> に渡された値は <code>yield</code> が受け取ります。最初 <code>next()</code> の呼び出しに値を渡しても常に無視されることに注意してください。</p> + +<div class="blockIndicator note"> +<p><strong>メモ:</strong> <code>next()</code> の<em>最初の</em>呼び出しに渡された値は常に無視されます。</p> +</div> + +<p>以下のフィボナッチ数列ジェネレーターでは数列を再起動するのに <code>next(x)</code> を使っています:</p> + +<pre class="brush: js notranslate">function* fibonacci() { + let current = 0; + let next = 1; + while (true) { + let reset = yield current; + [current, next] = [next, next + current]; + if (reset) { + current = 0; + next = 1; + } + } +} + +const sequence = fibonacci(); +console.log(sequence.next().value); // 0 +console.log(sequence.next().value); // 1 +console.log(sequence.next().value); // 1 +console.log(sequence.next().value); // 2 +console.log(sequence.next().value); // 3 +console.log(sequence.next().value); // 5 +console.log(sequence.next().value); // 8 +console.log(sequence.next(true).value); // 0 +console.log(sequence.next().value); // 1 +console.log(sequence.next().value); // 1 +console.log(sequence.next().value); // 2</pre> + +<p>ジェネレーターの {{jsxref("Global_Objects/Generator/throw","throw()")}} メソッドを呼び出して発生すべき例外値を渡すことで、ジェネレーターに例外を強制的に発生させることができます。これにより、まるで停止中の <code>yield</code> が <code>throw <em>value</em></code> 文に替わったかのように、ジェネレーターが停止した際の状況に応じて例外が発生します。</p> + +<p>例外がジェネレーター内部で捕捉されない場合は、<code>throw()</code> を通してその例外が呼び出し元へと伝播し、その後 <code>next()</code> を呼び出した結果の <code>done</code> プロパティは <code>true</code> となります。</p> + +<p>またジェネレーターは、与えられた値を返してジェネレーター自身の処理を終了させる {{jsxref("Global_Objects/Generator/return","return(value)")}} メソッドを持っています。</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Using_promises", "Web/JavaScript/Guide/Meta_programming")}}</p> diff --git a/files/ja/web/javascript/guide/keyed_collections/index.html b/files/ja/web/javascript/guide/keyed_collections/index.html new file mode 100644 index 0000000000..fbc979ab2b --- /dev/null +++ b/files/ja/web/javascript/guide/keyed_collections/index.html @@ -0,0 +1,161 @@ +--- +title: キー付きコレクション +slug: Web/JavaScript/Guide/Keyed_collections +tags: + - Collections + - Guide + - JavaScript + - Map + - 'l10n:priority' + - set +translation_of: Web/JavaScript/Guide/Keyed_collections +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</div> + +<p class="summary">本章では、キーによって順序付けされたデータのコレクションを紹介します。Map および Set オブジェクトは挿入順に反復処理を行える要素を保持します。</p> + +<h2 id="Maps" name="Maps">Map</h2> + +<h3 id="Map_object" name="Map_object"><code>Map</code> オブジェクト</h3> + +<p>ECMAScript 2015 で値と値とをマッピングする新しいデータ構造が導入されました。{{jsxref("Map")}} オブジェクトはシンプルなキー / バリューマップで、挿入順に要素を反復処理することができます。</p> + +<p>次のコードでは <code>Map</code> を用いたいくつかの基本的な操作を表しています。また、追加の例や全ての API については、{{jsxref("Map")}} リファレンスページをご覧ください。{{jsxref("Statements/for...of","for...of")}} ループを使って、各反復処理において <code>[key, value]</code> からなる配列を返しています。</p> + +<pre class="brush: js notranslate">let sayings = new Map(); +sayings.set('dog', 'woof'); +sayings.set('cat', 'meow'); +sayings.set('elephant', 'toot'); +sayings.size; // 3 +sayings.get('dog'); // woof +sayings.get('fox'); // undefined +sayings.has('bird'); // false +sayings.delete('dog'); +sayings.has('dog'); // false + +for (let [key, value] of sayings) { + console.log(key + ' goes ' + value); +} +// "cat goes meow" +// "elephant goes toot" + +sayings.clear(); +sayings.size; // 0 +</pre> + +<h3 id="Object_と_Map_との比較"><code>Object</code> と <code>Map</code> との比較</h3> + +<p>伝統的に、{{jsxref("Object", "objects", "", "1")}} は文字列を値にマップするのに使われてきました。オブジェクトを使うことで、キーを値に設定し、その値を取得し、キーを削除し、キーに対応する何かが格納されているかどうかを検出することができます、しかしながら、<code>Map</code> の方が少し便利です。</p> + +<ul> + <li><code>Object</code> のキーは {{jsxref("Global_Objects/String","Strings")}} オブジェクトです、<code>Map</code> ならどんな値も使えるというのに。</li> + <li><code>Map</code> は簡単にサイズを取得できます。<code>Object</code> はサイズを手作業で追跡する必要があります。</li> + <li><code>Map</code> の反復処理は要素の挿入順に行われます。</li> + <li><code>Object</code> はプロトタイプを持っているので、オブジェクトによるマップにはデフォルトキーが存在します(これは <code>map = Object.create(null)</code> を使って回避できます)。</li> +</ul> + +<p><code>Map</code> と <code>Object</code> のどちらを使用すべきかを決めるには下記の 3 つのヒントが役立つでしょう :</p> + +<ul> + <li>実行時までキーが不明なとき、またはすべてのキーが同じ型、すべての値が同じ型のときは Object よりも Map を使用しましょう。</li> + <li>プリミティブ値をキーとして保存する必要がある場合に Map を使用しましょう。Object はキーが数値、真偽値、もしくはいずれのプリミティブ値であるかどうかに関わらず、それぞれのキーを文字列として扱います。</li> + <li>個々の要素を操作するロジックがある場合は、Object を使用しましょう。</li> +</ul> + +<h3 id="WeakMap_object" name="WeakMap_object"><code>WeakMap</code> オブジェクト</h3> + +<p>{{jsxref("WeakMap")}} オブジェクトは、<strong>キーはオブジェクトのみ</strong>で<strong>、</strong>値は任意の値にできるキー / バリューのペアからなるコレクションです。キーによるオブジェクト参照は<strong>弱く</strong>保持され、そのオブジェクトへの参照が他に存在しないときはガベージコレクション (GC) の対象になります。<code>WeakMap</code> API は <code>Map</code> API と同じです。</p> + +<p><code>Map</code> オブジェクトとの違いの1つは、<code>WeakMap</code> のキーは列挙可能ではないことです(すなわち、キーのリストを取得するメソッドがありません)。もしも列挙可能であれば、リストは非決定性をもたらす、ガベージコレクションの状態に依存することになってしまいます。</p> + +<p>詳細やサンプルコードについては、{{jsxref("WeakMap")}} リファレンスページの「なぜ WeakMap なのか?」もご覧ください。</p> + +<p><code>WeakMap</code> オブジェクトのよくある使用方法のひとつとして、オブジェクトに対するプライベートデータの格納、あるいは実装の細部の隠蔽があります。次の例は Nick Fitzgerald 氏のブログ投稿、<a href="http://fitzgeraldnick.com/weblog/53/">"Hiding Implementation Details with ECMAScript 6 WeakMaps"</a>(ECMAScript 6 WeakMaps を使って実装の詳細を隠蔽する)です。プライベートなデータとメソッドはオブジェクトの内部に属していて、プライベートな WeakMap オブジェクトに格納されています。インスタンスから露出する全てとプロトタイプは公開されています、他の全てのものは外部よりアクセスできません。<code>privates</code> はモジュールから export されていません。</p> + +<pre class="brush: js notranslate">const privates = new WeakMap(); + +function Public() { + const me = { + // ここにプライベートデータが置かれる + }; + privates.set(this, me); +} + +Public.prototype.method = function () { + const me = privates.get(this); + // `me` にプライベートデータを詰め込む… +}; + +module.exports = Public;</pre> + +<h2 id="Sets" name="Sets">Set</h2> + +<h3 id="Set_object" name="Set_object"><code>Set</code> オブジェクト</h3> + +<p>{{jsxref("Set")}} オブジェクトは値によって構成されるコレクションです。挿入順に要素を反復処理することができます。<code>Set</code> の 1 つの値は 1 回だけ出現します; <code>Set</code> のコレクションでは値は一意です。</p> + +<p>次のコードでは <code>Set</code> を用いたいくつかの基本的な操作を表しています。また、追加の例や全ての API については、{{jsxref("Set")}} リファレンスページをご覧ください。</p> + +<pre class="brush: js notranslate">let mySet = new Set(); +mySet.add(1); +mySet.add('some text'); +mySet.add('foo'); + +mySet.has(1); // true +mySet.delete('foo'); +mySet.size; // 2 + +for (let item of mySet) console.log(item); +// 1 +// "some text" +</pre> + +<h3 id="Converting_between_Array_and_Set" name="Converting_between_Array_and_Set"><code>Array</code> と <code>Set</code> 間の変換</h3> + +<p>{{jsxref("Array.from")}} または <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_operator">スプレッド構文</a> を使用して <code>Set</code> から {{jsxref("Array")}} を生成できます。また、<code>Set</code> コンストラクタを使って <code>Array</code> から <code>Set</code> へと逆変換することができます。</p> + +<div class="blockIndicator note"> +<p><strong>注:</strong> <code>Set</code> オブジェクトは<em>一意の値</em>を格納することにくれぐれも注意してください、重複した要素は <code>Array</code> から変換するときに削除されます。</p> +</div> + +<pre class="brush: js notranslate">Array.from(mySet); +[...mySet2]; + +mySet2 = new Set([1, 2, 3, 4]); +</pre> + +<h3 id="Array_and_Set_compared" name="Array_and_Set_compared"><code>Array</code> と <code>Set</code> との比較</h3> + +<p>伝統的に、要素の集合は多くの状況において JavaScript の配列に格納されてきました。しかし、新しい <code>Set</code> オブジェクトにはいくつかの利点があります :</p> + +<ul> + <li>配列の {{jsxref("Array.indexOf", "indexOf")}} を使用してコレクションに要素が存在しているかどうかを調べるのは低速です。</li> + <li><code>Set</code> オブジェクトは値を使って要素を削除できます。配列の場合には要素のインデックを使い、スプライス(該当要素を取り除いて残りをつなぎ合わせる)操作が必要です。</li> + <li>{{jsxref("NaN")}} 値は配列の <code>indexOf</code> で検索することはできません。</li> + <li><code>Set</code> オブジェクトは一意の値を格納します、あなたが重複を気にする必要がありません。</li> +</ul> + +<h3 id="WeakSet_object" name="WeakSet_object"><code>WeakSet</code> オブジェクト</h3> + +<p>{{jsxref("WeakSet")}} オブジェクトは、オブジェクトのコレクションです。<code>WeakSet</code> 内の 1 つのオブジェクトは 1 回だけ出現します; <code>WeakSet</code> コレクション内では値は一意で、オブジェクトは列挙可能ではありません。</p> + +<p>{{jsxref("Set")}} オブジェクトとの主な違いは下記の通りです :</p> + +<ul> + <li><code>Set</code> とは対照的に、<code>WeakSet</code> は<strong>オブジェクトのみのコレクション</strong>で、任意の型の任意の値でのコレクションではありません。</li> + <li><code>WeakSet</code> は<em>弱い</em><strong> </strong>: コレクションでのオブジェクトでの参照は弱く保持されています。<code>WeakSet</code> 内に格納されているオブジェクトに対する参照がなくなった場合、ガベージコレクションされます。これはまた、現在コレクション内に格納されているオブジェクトのリストがないということを表しています。<code>WeakSet</code> は列挙可能ではありません。</li> +</ul> + +<p><code>WeakSet</code> オブジェクトの使用例は限定的です。メモリーリークが発生しないため、例えば、DOM 要素をキーとして使用し、監視するためにそれらにマーキングすることが安全に行なえます。</p> + +<h2 id="Key_and_value_equality_of_Map_and_Set" name="Key_and_value_equality_of_Map_and_Set"><code>Map</code> と <code>Set</code> におけるキーと値の等値性</h2> + +<p><code>Map</code> オブジェクトのキーの等値性と <code>Set</code> オブジェクトの値の等値性は両方とも、「<a href="https://tc39.github.io/ecma262/#sec-samevaluezero">same-value-zero アルゴリズム</a>」に基づいています:</p> + +<ul> + <li>等値性は原則として同値演算子 <code>===</code> のように判定されます。</li> + <li><code>-0</code> と <code>+0</code> は等しいと見なします。</li> + <li>{{jsxref("NaN")}} は(<code>===</code> とは逆に)自身と等しいと見なされます。</li> +</ul> + +<p>{{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</p> diff --git a/files/ja/web/javascript/guide/liveconnect_overview/index.html b/files/ja/web/javascript/guide/liveconnect_overview/index.html new file mode 100644 index 0000000000..4deeca4ad2 --- /dev/null +++ b/files/ja/web/javascript/guide/liveconnect_overview/index.html @@ -0,0 +1,799 @@ +--- +title: LiveConnect の概要 +slug: Web/JavaScript/Guide/LiveConnect_Overview +tags: + - Java + - JavaScript + - LiveConnect +translation_of: Archive/Web/LiveConnect/LiveConnect_Overview +--- +<p>この章では、Java のコードと JavaScript のコードが相互通信を可能にする技術である <a href="/ja/docs/LiveConnect" title="ja/docs/LiveConnect">LiveConnect</a> の使用方法を解説します。この章の読者は、Java プログラミングの経験があるものとします。</p> + +<h2 id="Working_with_Wrappers" name="Working_with_Wrappers">ラッパの使用</h2> + +<p>JavaScript において、<em>ラッパ</em>とは元の言語のオブジェクトをくるんだ、ターゲットとする言語のデータ型のオブジェクトです。JavaScript でプログラミングをするときは、ラッパオブジェクトを用いることで Java のメソッドやフィールドにアクセスすることができます。つまり、ラッパのメソッドを呼び出したりプロパティにアクセスすることで、Java のオブジェクトにおいて呼び出すことになります。Java 側では JavaScript のオブジェクトがクラス <code>netscape.javascript.JSObject</code> のインスタンスでラップされ、Java に渡されます。</p> + +<p>JavaScript のオブジェクトが Java に送られる際、ランタイムエンジンは <code>JSObject</code> 型の Java ラッパを生成します。一方 <code>JSObject</code> が Java から JavaScript に送られるときは、ランタイムエンジンはそのラップを解き、元の JavaScript オブジェクトの種類に戻します。<code>JSObject</code> クラスには、JavaScript のメソッドを呼び出したり JavaScript のプロパティを調べるためのインタフェースが備わっています。</p> + +<h2 id="JavaScript_to_Java_Communication" name="JavaScript_to_Java_Communication">JavaScript から Java への通信</h2> + +<p>Java のパッケージやクラスを参照したり、Java のオブジェクトや配列を扱ったりするときは、特別な LiveConnect オブジェクトを使用します。JavaScript から Java へのアクセスはすべて、これらのオブジェクトを用いて行います。それらのオブジェクトについて、以下の表で簡単にまとめます。</p> + +<table class="standard-table"> + <caption>表 9.1 LiveConnect オブジェクト</caption> + <thead> + <tr> + <th scope="col">オブジェクト</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>JavaArray</code></td> + <td>ラップされた Java の配列です。JavaScript コード内からアクセスされます。</td> + </tr> + <tr> + <td><code>JavaClass</code></td> + <td>Java のクラスへの JavaScript からの参照です。</td> + </tr> + <tr> + <td><code>JavaObject</code></td> + <td>ラップされた Java のオブジェクトです。JavaScript コード内からアクセスされます。</td> + </tr> + <tr> + <td><code>JavaPackage</code></td> + <td>Java のパッケージへの JavaScript からの参照です。</td> + </tr> + </tbody> +</table> + +<p><strong>注意:</strong> Java は強く型付けされた言語であり、JavaScript は弱く型付けされた言語であるため、LiveConnect を使用する際はもう一方の言語のために JavaScript ランタイムエンジンが引数の値を適当なデータ型に変換します。詳細は<a href="/ja/docs/JavaScript/Guide/Values,_Variables,_and_Literals#Data_type_conversion" title="ja/docs/JavaScript/Guide/Values, Variables, and Literals#Data Type Conversion">データ型の変換</a>をご覧ください。</p> + +<p>かなり直感的に Java とやりとりできることから、ある意味で LiveConnect オブジェクトの存在は透過的です。例えば、次のように Java の <code>String</code> オブジェクトを作成し、<code>new</code> 演算子を Java のコンストラクタとともに用いて、そのオブジェクトを JavaScript の変数 <code>myString</code> に代入することができます:</p> + +<pre class="brush: js">var myString = new java.lang.String("Hello world"); +</pre> + +<p>この例では、変数 <code>myString</code> は <code>JavaObject</code> になります。これは、Java の <code>String</code> オブジェクトのインスタンスを保持しているためです。<code>JavaObject</code> であるので、<code>myString</code> は <code>java.lang.String</code> およびそのスーパークラスである <code>java.lang.Object</code> のパブリックなインスタンスメソッドにアクセスできます。これらの Java のメソッドは JavaScript から、<code>JavaObject</code> のメソッドとして使用できます:</p> + +<pre class="brush: js">myString.length(); // 11 を返す +</pre> + +<p>JavaClass オブジェクトの静的メンバは直接呼び出すことができます。</p> + +<pre class="brush: js">alert(java.lang.Integer.MAX_VALUE); // 2147483647 というアラート +</pre> + +<h3 id="The_Packages_Object" name="The_Packages_Object">Packages オブジェクト</h3> + +<p>Java のクラスが <code>java</code>、<code>sun</code> あるいは <code>netscape</code> パッケージのいずれの一部でもない場合は、<code>Packages</code> オブジェクトを用いてそれにアクセスします。例えば Redwood 社が、実装したさまざまな Java のクラスを格納するための、<code>redwood</code> という名前の Java パッケージを使用することを想定します。<code>redwood</code> の <code>HelloWorld</code> クラスのインスタンスを作成するには、次のようにそのクラスのコンストラクタにアクセスします:</p> + +<pre class="brush: js">var red = new Packages.redwood.HelloWorld(); +</pre> + +<p>デフォルトパッケージのクラス (すなわち、明示的にはパッケージに名前をつけていないクラス) にアクセスすることもできます。例えば、HelloWorld クラスが直接 <code>CLASSPATH</code> に入っており、またパッケージには入っていない場合は、次のようにしてそれにアクセスできます:</p> + +<pre class="brush: js">var red = new Packages.HelloWorld(); +</pre> + +<p>LiveConnect の <code>java</code>、<code>sun</code> および <code>netscape</code> オブジェクトはよく使用される Java のパッケージであるために、短縮記法が備わっています。例えば、次のように使用できます:</p> + +<pre class="brush: js">var myString = new java.lang.String("Hello world"); +</pre> + +<p>これは次のものを省略したものです:</p> + +<pre class="brush: js">var myString = new Packages.java.lang.String("Hello world"); +</pre> + +<h3 id="Working_with_Java_Arrays" name="Working_with_Java_Arrays">Java の配列の使用</h3> + +<p>Java のメソッドが配列を作成し、JavaScript からその配列を参照するときは、<code>JavaArray</code> を使用します。例えば、次のコードは int 型の要素を 10 個持つ <code>JavaArray x</code> を作成します:</p> + +<pre class="brush: js">var x = java.lang.reflect.Array.newInstance(java.lang.Integer, 10); +</pre> + +<p>JavaScript の <code>Array</code> オブジェクトのように、<code>JavaArray</code> にはその配列の要素数を返す <code>length</code> プロパティがあります。<code>Array.length</code> とは異なり、<code>JavaArray.length</code> は読み取り専用のプロパティです。これは、Java の配列は作成時に要素総数が固定されるためです。</p> + +<h3 id="Package_and_Class_References" name="Package_and_Class_References">パッケージおよびクラスの参照</h3> + +<p>JavaScript から Java のパッケージやクラスへの簡単な参照では、<code>JavaPackage</code> や <code>JavaClass</code> オブジェクトが作成されます。先の Redwood 社についての例では、例えば Packages.redwood という参照が JavaPackage オブジェクトです。同様に、<code>java.lang.String</code> のような参照は <code>JavaClass</code> オブジェクトです。</p> + +<p>ほとんどの場合は <code>JavaPackage</code> や <code>JavaClass</code> オブジェクトについて気にする必要はありません。ただ Java のパッケージを使うだけのことであり、LiveConnect がこれらのオブジェクトを透過的に生成するからです。LiveConnect がクラスの読み込みに失敗する場合があり、そのときは以下のようにして手動で読み込みを行う必要があります:</p> + +<pre class="brush: js">var Widgetry = java.lang.Thread.currentThread().getContextClassLoader().loadClass("org.mywidgets.Widgetry"); +</pre> + +<p>JavaScript 1.3 以前では <code>JavaClass</code> オブジェクトをパラメータとして Java のメソッドとして渡す際に、自動的には <code>java.lang.Class</code> のインスタンスに変換されません。そのため、<code>java.lang.Class</code> のインスタンスのラッパを作成しなければなりません。次の例では、<code>forName</code> メソッドがラッパオブジェクトである <code>theClass</code> を生成します。そしてそれを <code>newInstance</code> メソッドに渡し、配列を生成します。</p> + +<pre class="brush: js">// JavaScript 1.3 +var theClass = java.lang.Class.forName("java.lang.String"); +var theArray = java.lang.reflect.Array.newInstance(theClass, 5); +</pre> + +<p>JavaScript 1.4 以降では次の例のように、<code>JavaClass</code> オブジェクトをメソッドに直接渡すことができます:</p> + +<pre class="brush: js">// JavaScript 1.4 +var theArray = java.lang.reflect.Array.newInstance(java.lang.String, 5); +</pre> + +<h3 id="Arguments_of_Type_char" name="Arguments_of_Type_char">char 型の引数</h3> + +<p>JavaScript 1.4 以降では <code>char</code> 型の引数を必要とする Java のメソッドに、1 文字の文字列を渡すことができます。例えば、次のようにして文字列 "H" を <code>Character</code> コンストラクタに渡すことができます:</p> + +<pre class="brush: js">var c = new java.lang.Character("H"); +</pre> + +<p>JavaScript 1.3 以前では、このようなメソッドにはその文字の Unicode 値に対応する整数値を渡さなければなりません。例えば、次のコードも "H" という文字列を変数 <code>c</code> に代入するものです:</p> + +<pre class="brush: js">var c = new java.lang.Character(72); +</pre> + +<h3 id="Handling_Java_Exceptions_in_JavaScript" name="Handling_Java_Exceptions_in_JavaScript">JavaScript での Java 例外の処理</h3> + +<p>Java のコードは実行時に失敗すると、例外を投げます。JavaScript のコードが Java のデータメンバまたはメソッドにアクセスし、失敗すると、Java の例外が JavaScript に渡されます。これは、例外を処理できるようにするためです。JavaScript 1.4 からは <code>try...catch</code> 文でこの例外を受け取ることができます。(Mozilla 固有の LiveConnect コードが Mozilla 内でメンテナンスされていなかったため、この機能は (他の一部機能もあわせて) Gecko 1.9 で壊れています (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=391642" title="Try-catch sometimes does not catch Java LiveConnect exceptions but instead fails">バグ 391642</a> をご覧ください)。しかし Java 6 アップデート 11 および 12 での、Mozilla の汎用 (かつクロスブラウザの) <a href="/ja/docs/Plugins" title="ja/docs/Plugins">NPAPI</a> プラグインコードに依存する構築のサポートにより修復されました。)</p> + +<p>例えば、Java の <code>forName</code> メソッドを使用して Java のクラス名を <code>theClass</code> という変数に代入するとします。<code>forName</code> メソッドに渡す値が Java のクラス名に評価できなければ、そのメソッドは例外を投げます。次のようにして、例外を処理できるように <code>forName</code> 代入文を <code>try</code> ブロック内に置きます:</p> + +<pre class="brush: js">function getClass(javaClassName) { + try { + var theClass = java.lang.Class.forName(javaClassName); + } catch (e) { + return ("The Java exception is " + e); + } + return theClass; +} +</pre> + +<p>この例では、<code>javaClassName</code> が "java.lang.String" のような正当なクラス名に評価されると代入が成功します。<code>javaClassName</code> が "String" のような不正なクラス名に評価されると、<code>getClass</code> 関数が例外を受け取り、次のようなものを返します:</p> + +<pre>The Java exception is java.lang.ClassNotFoundException: String +</pre> + +<p>例外の型に基づいて特別な処理をするには <code>instanceof</code> 演算子を使用します:</p> + +<pre class="brush: js">try { + // ... +} catch (e) { + if (e instanceof java.io.FileNotFound) { + // FileNotFound についての処理 + } else { + throw e; + } +} +</pre> + +<p>JavaScript の例外についての詳細情報は<a href="/ja/docs/JavaScript/Guide/Statements#Exception_Handling_Statements" title="ja/docs/JavaScript/Guide/Statements#Exception Handling Statements">例外処理文</a>を参照してください。</p> + +<h2 id="Java_to_JavaScript_Communication" name="Java_to_JavaScript_Communication">Java から JavaScript への通信</h2> + +<p>Java で JavaScript のオブジェクトを使用したい場合は、その Java ファイルに <code>netscape.javascript</code> パッケージをインポートしなければなりません。このパッケージは次のクラスを定義しています:</p> + +<ul> + <li><code><a href="/ja/docs/JavaScript/Reference/LiveConnect/JSObject" title="ja/docs/JavaScript/Reference/LiveConnect/JSObject">netscape.javascript.JSObject</a></code> : Java のコードから JavaScript のメソッドやプロパティにアクセスできるようにします。</li> + <li><code><a href="/ja/docs/JavaScript/Reference/LiveConnect/JSException" title="ja/docs/JavaScript/Reference/LiveConnect/JSException">netscape.javascript.JSException</a></code> : Java のコードで JavaScript のエラーを処理できるようにします。</li> +</ul> + +<p>これらのクラスの詳細は <a href="/ja/docs/JavaScript/Reference" title="ja/docs/JavaScript/Reference">JavaScript リファレンス</a>をご覧ください。</p> + +<h3 id="Locating_the_LiveConnect_classes" name="Locating_the_LiveConnect_classes">LiveConnect クラスの場所の特定</h3> + +<p>古いバージョンの Netscape ブラウザでは、これらのクラスがブラウザに同梱されていました。JavaScript 1.2 からは、これらのクラスは .jar ファイルに格納されています。それより古いバージョンの JavaScript では、これらのクラスは .zip ファイルに格納されています。例えば Windows NT 向けの Netscape Navigator 4 では、クラスは Navigator のディレクトリ直下の <code>Program\Java\Classes</code> ディレクトリ内の <code>java40.jar</code> ファイルに格納されています。</p> + +<p>より最近では、クラスは Sun の Java ランタイムに同梱されています。はじめはランタイムディストリビューションの "jre/lib" ディレクトリ内の "jaws.jar" ファイルに入っていましたが (JRE 1.3)、その後同じ場所の "plugin.jar" に移っています (JRE 1.4 以降)。</p> + +<h3 id="Using_the_LiveConnect_classes_with_the_JDK" name="Using_the_LiveConnect_classes_with_the_JDK">JDK での LiveConnect クラスの使用</h3> + +<p>LiveConnect クラスにアクセスするには、次のどちらかの方法で JDK コンパイラの <code>CLASSPATH</code> に .jar または .zip ファイルを配置します:</p> + +<ul> + <li><code>CLASSPATH</code> 環境変数を作成し、.jar または .zip ファイルのパスと名前を指定します。</li> + <li>コンパイル時に <code>-classpath</code> コマンドラインパラメータを用いて .jar または .zip ファイルの場所を指定する。</li> +</ul> + +<p>Windows NT では、コントロールパネルのシステムアイコンをダブルクリックし、<code>CLASSPATH</code> という名前のユーザ環境変数を作成し、それに次のような値を設定することで環境変数を作成できます:</p> + +<pre class="eval">C:\Program Files\Java\jre1.4.1\lib\plugin.jar +</pre> + +<p><code>CLASSPATH</code> についての詳細は Sun の JDK に関する資料をご覧ください。</p> + +<p><strong>注意:</strong> Java は強く型付けされた言語であり、JavaScript は弱く型付けされた言語であるため、LiveConnect を使用する際はもう一方の言語のために JavaScript ランタイムエンジンが引数の値を適当なデータ型に変換します。詳細は をご覧ください。</p> + +<h3 id="Using_the_LiveConnect_Classes" name="Using_the_LiveConnect_Classes">LiveConnect クラスの使用</h3> + +<p>すべての JavaScript オブジェクトは、Java コード内では <code>netscape.javascript.JSObject</code> のインスタンスとして現れます。Java コード内でメソッドを呼び出すときに、その引数として JavaScriptのオブジェクトを渡すことができます。そうするためには、そのメソッドの対応する仮パラメータを <code>JSObject</code> 型で定義しなければなりません。</p> + +<p>さらに、Java コード内で JavaScript のオブジェクトを使用するたびに、<code>netscape.javascript.JSException</code> 型の例外を処理する <code>try...catch</code> 文の内側で、その JavaScript オブジェクトを呼び出すようにしてください。こうすることで <code>JSException</code> 型の例外として Java で現れる、JavaScript コードの実行におけるエラーを Java コードで処理できるようになります。</p> + +<h4 id="Accessing_JavaScript_with_JSObject" name="Accessing_JavaScript_with_JSObject">JSObject を用いた JavaScript へのアクセス</h4> + +<p>例えば、<code>JavaDog</code> という Java のクラスを使用するとします。次のコードで示すように、<code>JavaDog</code> コンストラクタは JavaScript のオブジェクトである <code>jsDog</code> を引数としてとります。このオブジェクトは <code>JSObject</code> 型として定義されています:</p> + +<pre class="brush: java">import netscape.javascript.*; + +public class JavaDog{ + public String dogBreed; + public String dogColor; + public String dogSex; + + // クラスコンストラクタの定義 + public JavaDog(JSObject jsDog){ + // ここで try...catch を使用して JSExceptions を処理できるようにする + this.dogBreed = (String)jsDog.getMember("breed"); + this.dogColor = (String)jsDog.getMember("color"); + this.dogSex = (String)jsDog.getMember("sex"); + } +} +</pre> + +<p><code>JSObject</code> の <code>getMember</code> メソッドは、JavaScript のオブジェクトのプロパティにアクセスするために使用するものです。この例では JavaScript のプロパティである <code>jsDog.breed</code> の値を Java のデータメンバである <code>JavaDog.dogBreed</code> に代入するために、<code>getMember</code> を使用しています。</p> + +<p><strong>注意:</strong> より現実的な例では <code>try...catch</code> 文の内側で <code>getMember</code> を呼び出し、<code>JSException</code> 型のエラーを処理できるようにします。詳細は、Java での JavaScript の例外処理を参照してください。</p> + +<p><code>getMember</code> の動作をさらに知るために、JavaScript の <code>Dog</code> オブジェクトを作成し、その定義を見てみます:</p> + +<pre class="brush: js">function Dog(breed,color,sex){ + this.breed = breed; + this.color = color; + this.sex = sex; +} +</pre> + +<p><code>Dog</code> の JavaScript のインスタンスである <code>gabby</code> は、次のようにして作ることができます:</p> + +<pre class="brush: js">var gabby = new Dog("lab", "chocolate", "female"); +</pre> + +<p><code>gabby.color</code> を評価すると、それが "chocolate" という値を持っていることがわかります。ここで次のように <code>gabby</code> オブジェクトをコンストラクタに渡し、JavaScript コードで <code>JavaDog</code> のインスタンスを作成することにします:</p> + +<pre class="brush: js">var javaDog = new Packages.JavaDog(gabby); +</pre> + +<p><code>javaDog.dogColor</code> を評価すると、それも "chocolate" という値を持っていることがわかります。これは Java のコンストラクタ内の <code>getMember</code> メソッドが、<code>gabby.color</code> の値を <code>dogColor</code> に代入するからです。</p> + +<h4 id="Handling_JavaScript_Exceptions_in_Java" name="Handling_JavaScript_Exceptions_in_Java">Java での JavaScript の例外処理</h4> + +<p>実行時に Java からの JavaScript コードの呼び出しに失敗すると、例外が投げられます。Java から JavaScript コードを呼び出すときに、<code>try...catch</code> 文でこの例外を受け取ることができます。JavaScript の例外は、<code>netscape.javascript.JSException</code> のインスタンスとして Java コードから扱えます。</p> + +<p><code>JSException</code> は JavaScript が投げるあらゆる種類の例外に対応する、Java のラッパです。<code>JSObject</code> のインスタンスが JavaScript のオブジェクトのラッパであるのと同じようなものです。Java で JavaScript コードを評価するときは <code>JSException</code> を使用してください。</p> + +<p>Java で JavaScript コードを評価する際、次の状況でランタイムエラーが発生します:</p> + +<ul> + <li>JavaScript コンパイルエラーまたは 実行時に生じた 他のエラーにより、JavaScript コードが評価されません。JavaScript インタプリタは、<code>JSException</code> のインスタンスに変換されるエラーメッセージを生成します。</li> + <li>Java は正常に JavaScript のコードを評価しましたが、処理方法が定かでない <code>throw</code> 文をJavaScript コードが実行します。JavaScript は、<code>JSException</code> のインスタンスとしてラップされる例外を投げます。Java でこの例外のラップを解くには、<code>JSException</code> の <code>getWrappedException</code> メソッドを使用します。</li> +</ul> + +<p>例えば、Java のオブジェクトである <code>jsCode</code> が自身に渡される文字列 <code>eTest</code> を評価するとします。次のようなエラー処理を実行することで、評価が原因で発生するどちらの種類のランタイムエラーにも対応できます:</p> + +<pre class="brush: java">import netscape.javascript.JSObject; +import netscape.javascript.JSException; + +public class eTest { + public static Object doit(JSObject obj, String jsCode) { + try { + obj.eval(jsCode); + } catch (JSException e) { + if (e.getWrappedException() == null) + return e; + return e.getWrappedException(); + } + return null; + } +} +</pre> + +<p>この例では、渡された文字列 <code>jsCode</code> を <code>try</code> ブロック内のコードが評価しようとします。文字列 "<code>myFunction()</code>" を <code>jsCode</code> の値として渡すとします。<code>myFunction</code> が JavaScript の関数として定義されていない場合、JavaScript インタプリタは <code>jsCode</code> を評価できません。インタプリタはエラーメッセージを生成し、Java のハンドラがそのメッセージを受け取り、<code>doit</code> メソッドは <code>netscape.javascript.JSException</code> のインスタンスを返します。</p> + +<p>しかし、次のように <code>myFunction</code> が JavaScript で定義されているとします:</p> + +<pre class="brush: js">function myFunction() { + try { + if (theCondition == true) { + return "Everything's ok"; + } else { + throw "JavaScript error occurred"; + } + } catch (e) { + if (canHandle == true) { + handleIt(); + } else { + throw e; + } + } +} +</pre> + +<p><code>theCondition</code> が false であれば、関数は例外を投げます。その例外は JavaScript コードで受け取られ、さらに <code>canHandle</code> が true の場合に JavaScript はそれを処理します。<code>canHandle</code> false がならばその例外が再び投げられ、Java のハンドラがそれを受け取り、 <code>doit</code> メソッドが次の Java の文字列を返します:</p> + +<pre>JavaScript error occurred +</pre> + +<p>JavaScript の例外についての詳細情報は<a href="/ja/docs/JavaScript/Guide/Statements#Exception_Handling_Statements" title="ja/docs/JavaScript/Guide/Statements#Exception Handling Statements">例外処理文</a>を参照してください。</p> + +<h4 id="Backward_Compatibility" name="Backward_Compatibility">後方互換性</h4> + +<p>JavaScript 1.3 以前のバージョンでは、<code>JSException</code> クラスには省略可能な文字列引数をとる 3 つの public タイプのコンストラクタがありました。この文字列引数は、詳細なメッセージやその例外に対する他の情報を指定するものです。<code>getWrappedException</code> メソッドは使用できませんでした。</p> + +<p>次のような <code>try...catch</code> 文を使用することで、JavaScript 1.3 以前のバージョンで LiveConnect の例外を処理できます:</p> + +<pre class="brush: js">try { + global.eval("foo.bar = 999;"); +} catch (Exception e) { + if (e instanceof JSException) { + jsCodeFailed(); + } else { + otherCodeFailed(); + } +} +</pre> + +<p>この例では <code>foo</code> が定義されていないと <code>eval</code> 文が失敗します。<code>try</code> ブロックの <code>eval</code> 文が <code>JSException</code> を投げると、<code>catch</code> ブロックが <code>jsCodeFailed</code> メソッドを実行します。<code>try</code> ブロックがそれ以外のエラーを投げると、<code>otherCodeFailed</code> メソッドが実行されます。</p> + +<h2 id="Data_Type_Conversions" name="Data_Type_Conversions">データ型変換</h2> + +<p>Java は強く型付けされた言語であり、JavaScript は弱く型付けされた言語であるため、LiveConnect を使用する際はもう一方の言語のために、JavaScript ランタイムエンジンが引数の値を適切なデータ型に変換します。この変換について以下のセクションで説明します:</p> + +<ul> + <li>JavaScript から Java への変換</li> + <li>Java からJavaScript への変換</li> +</ul> + +<h3 id="JavaScript_to_Java_Conversions" name="JavaScript_to_Java_Conversions">JavaScript から Java への変換</h3> + +<p>JavaScript から Java のメソッドを呼び出してパラメータを渡す際、渡すパラメータのデータ型は以下のセクションで説明するルールによって変換されます:</p> + +<ul> + <li>数値</li> + <li>真偽値</li> + <li>文字列値</li> + <li>undefined 値</li> + <li>null 値</li> + <li>JavaArray および JavaObject オブジェクト</li> + <li>JavaClass オブジェクト</li> + <li>その他の JavaScript オブジェクト</li> +</ul> + +<p><code>netscape.javascript.JSObject</code> メソッドの戻り値は常に <code>java.lang.Object</code> のインスタンスに変換されます。このような戻り値の変換ルールもここで説明します。</p> + +<p>例えば <code>JSObject.eval</code> が JavaScript の数値を返すのであれば、この数値を <code>java.lang.Object</code> のインスタンスに変換するルールは数値に記載されています。</p> + +<h4 id="Number_Values" name="Number_Values">数値</h4> + +<p>Java のメソッドに JavaScript の数値型をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Java のパラメータ型</th> + <th scope="col">変換ルール</th> + </tr> + </thead> + <tbody> + <tr> + <td>double</td> + <td> + <ul> + <li>そのままの値が、丸められたり絶対値や符号が損なわれることなく Java に渡されます。</li> + <li><code>NaN</code> は <code>NaN</code> に変換されます。</li> + </ul> + </td> + </tr> + <tr> + <td>java.lang.Double<br> + java.lang.Object</td> + <td><code>java.lang.Double</code> の新しいインスタンスが作成され、そのままの値が、丸められたり絶対値や符号が損なわれることなく Java に渡されます。</td> + </tr> + <tr> + <td>float</td> + <td> + <ul> + <li>値は float 精度に丸められます。</li> + <li>大きすぎまたは小さすぎて表現できない値は、正の無限大または負の無限大に丸められます。</li> + <li><code>NaN</code> は <code>NaN</code> に変換されます。</li> + </ul> + </td> + </tr> + <tr> + <td>byte<br> + char<br> + int<br> + long<br> + short</td> + <td> + <ul> + <li>値は負の無限大方向に丸められます。</li> + <li>大きすぎまたは小さすぎて表現できない値は、ランタイムエラーになります。</li> + <li><code>NaN</code> は変換されずにランタイムエラーになります。</li> + </ul> + </td> + </tr> + <tr> + <td><code>java.lang.String</code></td> + <td>値は文字列に変換されます。例えば: + <ul> + <li>237 は "237" になります。</li> + </ul> + </td> + </tr> + <tr> + <td>boolean</td> + <td> + <ul> + <li>0 および <code>NaN</code> は false に変換されます。</li> + <li>その他の値は true に変換されます。</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<p><code>java.lang.String</code> のインスタンスをパラメータに想定した Java のメソッドに JavaScript の数値をパラメータとして渡すと、その数値は文字列に変換されます。<code>equals()</code> メソッドを使用すると、この変換結果と他の文字列を比較できます。</p> + +<h4 id="Boolean_Values" name="Boolean_Values">真偽値</h4> + +<p>Java のメソッドに JavaScript の真偽値型をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Java のパラメータ型</th> + <th scope="col">変換ルール</th> + </tr> + </thead> + <tbody> + <tr> + <td>boolean</td> + <td>すべての値は、Java で対応するものに直接変換されます。</td> + </tr> + <tr> + <td><code>java.lang.Boolean</code><br> + <code>java.lang.Object</code></td> + <td><code>java.lang.Boolean</code> の新しいインスタンスが作成されます。同一のプリミティブ値に対して 1 つのインスタンスではなく、各パラメータについて新しいインスタンスが作成されます。</td> + </tr> + <tr> + <td><code>java.lang.String</code></td> + <td>値は文字列に変換されます。例えば: + <ul> + <li>true は "true" になります。</li> + <li>false は "false" になります。</li> + </ul> + </td> + </tr> + <tr> + <td>byte<br> + char<br> + double<br> + float<br> + int<br> + long<br> + short</td> + <td> + <ul> + <li>true は 1 になります。</li> + <li>false は 0 になります。</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<p><code>java.lang.String</code> のインスタンスをパラメータに想定した Java のメソッドに JavaScript の真偽値をパラメータとして渡すと、その真偽値は文字列に変換されます。== 演算子を使用すると、この変換結果と他の文字列を比較できます。</p> + +<h4 id="String_Values" name="String_Values">文字列値</h4> + +<p>Java のメソッドに JavaScript の文字列型をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Java のパラメータ型</th> + <th scope="col">変換ルール</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>java.lang.String</code><br> + <code>java.lang.Object</code></td> + <td>JavaScript 1.4: + <ul> + <li>JavaScript の文字列は、Unicode 値で <code>java.lang.String</code> のインスタンスに変換されます。</li> + </ul> + + <p>JavaScript 1.3 以前:</p> + + <ul> + <li>JavaScript の文字列は、ASCII 値で <code>java.lang.String</code> のインスタンスに変換されます。</li> + </ul> + </td> + </tr> + <tr> + <td>byte<br> + double<br> + float<br> + int<br> + long<br> + short</td> + <td>すべての値は、ECMA-262 に記載に従って数値に変換されます。JavaScript の文字列値は ECMA-262 に記載されたルールに従って数値に変換されます。</td> + </tr> + <tr> + <td>char</td> + <td>JavaScript 1.4: + <ul> + <li>1 文字の文字列は、Unicode 文字に変換されます。</li> + <li>他のすべての値は数値に変換されます。</li> + </ul> + + <p>JavaScript 1.3 以前:</p> + + <ul> + <li>すべての値が数値に変換されます。</li> + </ul> + </td> + </tr> + <tr> + <td>boolean</td> + <td> + <ul> + <li>空文字列は false になります。</li> + <li>他のすべての値は true になります。</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<h4 id="Undefined_Values" name="Undefined_Values">undefined 値</h4> + +<p>Java のメソッドに JavaScript の undefined 値をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Java のパラメータ型</th> + <th scope="col">変換ルール</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>java.lang.String</code><br> + <code>java.lang.Object</code></td> + <td>値は java.lang.String のインスタンスに変換され、インスタンスの値は文字列 "undefined" になります。</td> + </tr> + <tr> + <td>boolean</td> + <td>値は false になります。</td> + </tr> + <tr> + <td>double<br> + float</td> + <td>値は <code>NaN</code> になります。</td> + </tr> + <tr> + <td>byte<br> + char<br> + int<br> + long<br> + short</td> + <td>値は 0 になります。</td> + </tr> + </tbody> +</table> + +<p>undefined 値の変換は JavaScript 1.3 以降でのみ可能です。それより古いバージョンでは、undefined 値がサポートされていません。</p> + +<p><code>java.lang.String</code> のインスタンスをパラメータに想定した Java のメソッドに JavaScript の undefined 値をパラメータとして渡すと、その undefined 値は文字列に変換されます。== 演算子を使用すると、この変換結果と他の文字列を比較できます。</p> + +<h4 id="Null_Values" name="Null_Values">null 値</h4> + +<p>Java のメソッドに JavaScript の null 値をパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Java のパラメータ型</th> + <th scope="col">変換ルール</th> + </tr> + </thead> + <tbody> + <tr> + <td>あらゆるクラス<br> + あらゆるインタフェースの種類</td> + <td>値は null になります。</td> + </tr> + <tr> + <td>byte<br> + char<br> + double<br> + float<br> + int<br> + long<br> + short</td> + <td>値は 0 になります。</td> + </tr> + <tr> + <td>boolean</td> + <td>値は false になります。</td> + </tr> + </tbody> +</table> + +<h4 id="JavaArray_and_JavaObject_objects" name="JavaArray_and_JavaObject_objects">JavaArray および JavaObject オブジェクト</h4> + +<p>ほとんどの場合、Java のメソッドに JavaScript の <code>JavaArray</code> または <code>JavaObject</code> オブジェクトをパラメータとして渡すと、Java は単にそのオブジェクトのラップを解きます。そうでない場合は、Java は次の表で示すルールに従ってそのオブジェクトを別のデータ型に変換します:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Java のパラメータ型</th> + <th scope="col">変換ルール</th> + </tr> + </thead> + <tbody> + <tr> + <td>ラップが解かれたオブジェクトと代入互換性のある、あらゆるインタフェースまたはクラス</td> + <td>オブジェクトのラップが解かれます。</td> + </tr> + <tr> + <td><code>java.lang.String</code></td> + <td>オブジェクトのラップが解かれ、ラップが解かれた Java オブジェクトの <code>toString</code> メソッドが呼び出され、その結果が <code>java.lang.String</code> の新しいインスタンスとして返されます。</td> + </tr> + <tr> + <td>byte<br> + char<br> + double<br> + float<br> + int<br> + long<br> + short</td> + <td>オブジェクトのラップが解かれ、次の状況のどちらかが起こります: + <ul> + <li>ラップが解かれた Java のオブジェクトに <code>doubleValue</code> メソッドがあれば、<code>JavaArray</code> または <code>JavaObject</code> はこのメソッドが返す値に変換されます。</li> + <li>ラップが解かれた Java オブジェクトに <code>doubleValue</code> メソッドがなければ、エラーが発生します。</li> + </ul> + </td> + </tr> + <tr> + <td>boolean</td> + <td>JavaScript 1.3 以降ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります: + <ul> + <li>オブジェクトが null ならば、false に変換されます。</li> + <li>オブジェクトがそれ以外の値ならば、true に変換されます。</li> + </ul> + + <p>JavaScript 1.2 以前ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:</p> + + <ul> + <li>ラップが解かれたオブジェクトに <code>booleanValue</code> メソッドがあれば、ソースオブジェクトは戻り値のために変換されます。</li> + <li>オブジェクトに <code>booleanValue</code> がなければ、変換に失敗します。</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<p>ラップが解かれたオブジェクトが Java のパラメータ型のインスタンスであれば、インタフェースまたはクラスが、ラップが解かれたオブジェクトと代入互換性があるということです。つまり、次の文は必ず true を返します:</p> + +<pre class="brush: js">unwrappedObject instanceof parameterType; +</pre> + +<h4 id="JavaClass_objects" name="JavaClass_objects">JavaClass オブジェクト</h4> + +<p>Java のメソッドに JavaScript の <code>JavaClass</code> オブジェクトをパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Java のパラメータ型</th> + <th scope="col">変換ルール</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>java.lang.Class</code></td> + <td>オブジェクトのラップが解かれます。</td> + </tr> + <tr> + <td><code>netscape.javascript.JSObject</code><br> + <code>java.lang.Object</code></td> + <td><code>JavaClass</code> オブジェクトが <code>netscape.javascript.JSObject</code> の新しいインスタンス内にラップされます。</td> + </tr> + <tr> + <td><code>java.lang.String</code></td> + <td>オブジェクトのラップが解かれ、ラップが解かれた Java オブジェクトの <code>toString</code> メソッドが呼び出され、その結果が <code>java.lang.String</code> の新しいインスタンスとして返されます。</td> + </tr> + <tr> + <td>boolean</td> + <td>JavaScript 1.3 以降ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります: + <ul> + <li>オブジェクトが null ならば、false に変換されます。</li> + <li>オブジェクトがそれ以外の値ならば、true に変換されます。</li> + </ul> + + <p>JavaScript 1.2 以前ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:</p> + + <ul> + <li>ラップが解かれたオブジェクトに <code>booleanValue</code> メソッドがあれば、ソースオブジェクトは戻り値のために変換されます。</li> + <li>オブジェクトに <code>booleanValue</code> がなければ、変換に失敗します。</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<h4 id="Other_JavaScript_objects" name="Other_JavaScript_objects">その他の JavaScript のオブジェクト</h4> + +<p>Java のメソッドに JavaScript のその他のオブジェクトをパラメータとして渡すと、Java は次の表で示すルールに従ってその値を変換します:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Java のパラメータ型</th> + <th scope="col">変換ルール</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>netscape.javascript.JSObject</code><br> + <code>java.lang.Object</code></td> + <td>オブジェクトは <code>netscape.javascript.JSObject</code> の新しいインスタンス内にラップされます。</td> + </tr> + <tr> + <td><code>java.lang.String</code></td> + <td>オブジェクトのラップが解かれ、ラップが解かれたオブジェクトの <code>toString</code> メソッドが呼び出され、その結果が <code>java.lang.String</code> の新しいインスタンスとして返されます。</td> + </tr> + <tr> + <td>byte<br> + char<br> + double<br> + float<br> + int<br> + long<br> + short</td> + <td>オブジェクトは、ECMA-262 に記載された <code>ToPrimitive</code> 演算子のロジックを使用して値に変換されます。この演算子で使用される <em>PreferredType</em> ヒントは Number です。</td> + </tr> + <tr> + <td>boolean</td> + <td>JavaScript 1.3 以降ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります: + <ul> + <li>オブジェクトが null ならば、false に変換されます。</li> + <li>オブジェクトがそれ以外の値ならば、true に変換されます。</li> + </ul> + + <p>JavaScript 1.2 以前ではオブジェクトのラップが解かれ、次の状況のどちらかが起こります:</p> + + <ul> + <li>ラップが解かれたオブジェクトに <code>booleanValue</code> メソッドがあれば、ソースオブジェクトは戻り値のために変換されます。</li> + <li>オブジェクトに <code>booleanValue</code> がなければ、変換に失敗します。</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<h3 id="Java_to_JavaScript_Conversions" name="Java_to_JavaScript_Conversions">Java から JavaScript への変換</h3> + +<p>Java から JavaScript に渡された値は、次のように変換されます:</p> + +<ul> + <li>Java の byte、char、short、int、long、float および double は、JavaScript の数値に変換されます。</li> + <li>Java の boolean は、JavaScript の真偽値に変換されます。</li> + <li>クラス <code>netscape.javascript.JSObject</code> のオブジェクトは、元の JavaScript のオブジェクトに変換されます。</li> + <li>Java の配列は JavaScript の擬似的な Array オブジェクトに変換されます。このオブジェクトは JavaScript の <code>Array</code> オブジェクトと全く同じような挙動をとります。つまり、<code>arrayName[index]</code> (<code>index</code> は整数) という構文でそれにアクセスでき、その長さを <code>arrayName.length</code> で判断できます。</li> + <li>Java のそれ以外オブジェクトは、JavaScript のラッパに変換されます。このラッパを通じて Java のオブジェクトのメソッドやフィールドにアクセスできます: + <ul> + <li>このラッパから文字列への変換では、元のオブジェクトで <code>toString</code> メソッドが呼び出されます。</li> + <li>数値への変換では、可能であれば <code>doubleValue</code> メソッドが呼び出され、そうでなければ失敗します。</li> + <li>JavaScript 1.3 以降の真偽値への変換では、そのオブジェクトが null であれば false が、そうでなければ true を返します。</li> + <li>JavaScript 1.2 以前の真偽値への変換では、可能であれば <code>booleanValue</code> メソッドが呼び出され、そうでなければ失敗します。</li> + </ul> + </li> +</ul> + +<p>java.lang.Double および java.lang.Integer のインスタンスは、JavaScript の数値ではなく JavaScript のオブジェクトに変換されることに注意してください。同様に java.lang.String のインスタンスも、JavaScript の文字列ではなく JavaScript のオブジェクトに変換されます。</p> + +<p>Java の <code>String</code> オブジェクトも、JavaScript のラッパに相当します。JavaScript の文字列を必要とする JavaScript のメソッドを、このラッパを渡して呼び出すとエラーになります。そうではなく、次のようにラッパに空文字列を付加することで、ラッパを JavaScript の文字列に変換してください:</p> + +<pre class="brush: js">var JavaString = JavaObj.methodThatReturnsAString(); +var JavaScriptString = JavaString + "";</pre> diff --git a/files/ja/web/javascript/guide/loop_statements/break_statement/index.html b/files/ja/web/javascript/guide/loop_statements/break_statement/index.html new file mode 100644 index 0000000000..35cc94abdf --- /dev/null +++ b/files/ja/web/javascript/guide/loop_statements/break_statement/index.html @@ -0,0 +1,24 @@ +--- +title: break 文 +slug: Web/JavaScript/Guide/Loop_Statements/break_Statement +--- +<h3 id="break_.E6.96.87" name="break_.E6.96.87">break 文</h3> +<p><code>break</code> 文は <code>loop</code> 文や <code>switch</code> 文、<code>label</code> 文から抜け出すために使用します。</p> +<ul> + <li><code>break</code> にラベルを使用しないと、最も内側にある <code>while</code> や <code>do-while</code>、<code>for</code>、<code>switch</code> から抜け、続く文にコントロールを移します。</li> + <li><code>break</code> にラベルを使用すると、指定されたラベルの付いた文から抜けます。</li> +</ul> +<p>break 文は次のように使用します。</p> +<ol> + <li><code>break;</code></li> + <li><code>break label;</code></li> +</ol> +<p>1番目の形式の構文は最も内側のループもしくは <code>switch</code> から抜けます。2番目の形式の構文は指定した label 文から抜けます。</p> +<p><strong>例</strong><br> + 次の例は、その値が <code>theValue</code> である要素のインデックスが見つかるまで、配列の要素について繰り返します。</p> +<pre>for (i = 0; i < a.length; i++) { + if (a[i] == theValue) + break; +} +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Loop_Statements/label_Statement", "JavaScript/Guide/Loop_Statements/continue_Statement") }}</p> diff --git a/files/ja/web/javascript/guide/loop_statements/continue_statement/index.html b/files/ja/web/javascript/guide/loop_statements/continue_statement/index.html new file mode 100644 index 0000000000..f7a5697eeb --- /dev/null +++ b/files/ja/web/javascript/guide/loop_statements/continue_statement/index.html @@ -0,0 +1,46 @@ +--- +title: continue 文 +slug: Web/JavaScript/Guide/Loop_Statements/continue_Statement +--- +<h3 id="continue_.E6.96.87" name="continue_.E6.96.87">continue 文</h3> +<p><code>continue</code> 文は <code>while</code> 文、<code>do-while</code> 文、<code>for</code> 文、<code>label</code> 文をリスタートさせるために用います。</p> +<ul> + <li>ラベルを用いずに <code>continue</code> を使用した場合、現在繰り返している最も内側にある <code>while</code> 文 <code>do-while</code> 文、<code>for</code> 文を終了し、次の反復の実行に移ります。<code>break</code> 文とは異なり、<code>continue</code> はループ全体の実行を終了しません。<code>while</code> ループでは条件比較部分に戻ります。<code>for</code> ループではインクリメントの式に移ります。</li> + <li>ラベルを用いて <code>continue</code> を使用した場合、<code>label</code> で指定されたループ文に移ります。</li> +</ul> +<p><code>continue</code> 文は次のように使用します。</p> +<ol> + <li><code>continue</code></li> + <li><code>continue label</code></li> +</ol> +<p><strong>例 1</strong><br> + 次の例では、<code>i</code> の値が 3 のときに実行される <code>continue</code> 文を用いた <code>while</code> ループを示します。こうすることで <code>n</code> は順に 1、3、7、12 という値をとります。</p> +<pre class="eval">i = 0; +n = 0; +while (i < 5) { + i++; + if (i == 3) + continue; + n += i; +} +</pre> +<p><strong>例 2</strong><br> + <code>checkiandj</code> というラベルの付いた文の中に <code>checkj</code> というラベルの付いた文があります。<code>continue</code> に出くわすと、プログラムは <code>checkj</code> の現在の反復を終了し、次の反復を始めます。<code>continue</code> に出くわすたびに、条件が false になるまで <code>checkj</code> を繰り返します。false が返されると <code>checkiandj</code> 文の残りを完了し、条件が false を返すまで <code>checkiandj</code> を繰り返します。false が返されると <code>checkiandj</code> に続く文が実行されます。</p> +<p><code>continue</code> が <code>checkiandj</code> というラベルを持っているとプログラムは <code>checkiandj</code> 文の最初から続けます。</p> +<pre>checkiandj : + while (i < 4) { + document.write(i + "<br/>"); + i += 1; + checkj : + while (j > 4) { + document.write(j + "<br/>"); + j -= 1; + if ((j % 2) == 0) + continue checkj; + document.write(j + " is odd.<br/>"); + } + document.write("i = " + i + "<br/>"); + document.write("j = " + j + "<br/>"); + } +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Loop_Statements/break_Statement", "JavaScript/Guide/Object_Manipulation_Statements") }}</p> diff --git a/files/ja/web/javascript/guide/loop_statements/do...while_statement/index.html b/files/ja/web/javascript/guide/loop_statements/do...while_statement/index.html new file mode 100644 index 0000000000..6e1df1e586 --- /dev/null +++ b/files/ja/web/javascript/guide/loop_statements/do...while_statement/index.html @@ -0,0 +1,19 @@ +--- +title: do...while 文 +slug: Web/JavaScript/Guide/Loop_Statements/do...while_Statement +--- +<h3 id="do...while_.E6.96.87" name="do...while_.E6.96.87">do...while 文</h3> +<p><code>do...while</code> 文は指定した条件が false に評価されるまで繰り返します。<code>do...while</code> 文は次のように使用します。</p> +<pre class="eval">do + statement +while (condition); +</pre> +<p><code>statement</code> は条件がチェックされる前に一度実行されます。複数の文を実行するにはブロック文 (<code>{ ... }</code>) を使用して文をグループ化してください。<code>condition</code> が true の場合、その文が再び実行されます。毎回実行された後に条件がチェックされます。条件が false ときは実行が停止され、コントロールが <code>do...while</code> の後に続く文に渡されます。</p> +<p><strong>例</strong><br> + 次の例では do ループは最低 1 回は反復され、i が 5 より小さくなくなるまで反復されます。</p> +<pre class="eval">do { + i += 1; + document.write(i); +} while (i < 5); +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Loop_Statements/for_Statement", "JavaScript/Guide/Loop_Statements/while_Statement") }}</p> diff --git a/files/ja/web/javascript/guide/loop_statements/for_statement/index.html b/files/ja/web/javascript/guide/loop_statements/for_statement/index.html new file mode 100644 index 0000000000..b2dccec25b --- /dev/null +++ b/files/ja/web/javascript/guide/loop_statements/for_statement/index.html @@ -0,0 +1,50 @@ +--- +title: for 文 +slug: Web/JavaScript/Guide/Loop_Statements/for_Statement +--- +<h3 id="for_.E6.96.87" name="for_.E6.96.87">for 文</h3> +<p><code>for</code> ループは指定した条件が false に評価されるまで繰り返します。JavaScript の for ループは Java や C の for ループに似ています。<code>for</code> 文は次のように使用します。</p> +<pre class="eval">for ([initialExpression]; [condition]; [incrementExpression]) + statement +</pre> +<p><code>for</code> ループを実行すると以下のことが起こります。</p> +<ol> + <li>初期化式 <code>initialExpression</code> があれば実行されます。この式は通常、1 つかそれ以上のループカウンタを初期化しますが、構文的にはある程度複雑な式も指定できます。また、この式は変数を宣言することもできます。</li> + <li><code>condition</code> 式が評価されます。<code>condition</code> の値が true であればループ文が実行されます。<code>condition</code> が false の場合は <code>for</code> ループは終了します。<code>condition</code> 式が完全に省略されている場合、条件は true であると仮定されます。</li> + <li><code>statement</code> が実行されます。複数の式を実行するにはブロック文 (<code>{ ... }</code>) を使用して文をグループ化してください。</li> + <li>更新式 <code>incrementExpression</code> があれば実行されます。そしてコントロールがステップ 2 に戻ります。</li> +</ol> +<p><strong>例</strong><br> + 次の関数には、スクローリングリスト(複数選択できる Select オブジェクト)で選択されたオプションの数を数える <code>for</code> 文が含まれています。<code>for</code> 文では変数 <code>i</code> が宣言され、それが 0 に初期化されています。<code>i</code> が <code>Select</code> オブジェクトのオプションの個数より小さいかをチェックし、続く <code>if</code> 文を実行し、ループが 1 回りしたら <code>i</code> を 1 だけ増加させます。</p> +<pre><script type="text/javascript">//<![CDATA[ + +function howMany(selectObject) { + var numberSelected = 0; + for (var i = 0; i < selectObject.options.length; i++) { + if (selectObject.options[i].selected) + numberSelected++; + } + return numberSelected; +} + +//]]></script> +<form name="selectForm"> + <p> + <strong>Choose some music types, then click the button below:</strong> + <br/> + <select name="musicTypes" multiple="multiple"> + <option selected="selected">R&B</option> + <option>Jazz</option> + <option>Blues</option> + <option>New Age</option> + <option>Classical</option> + <option>Opera</option> + </select> + </p> + <p> + <input type="button" value="How many are selected?" + onclick="alert ('Number of options selected: ' + howMany(document.selectForm.musicTypes))"/> + </p> +</form> +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Loop_Statements", "JavaScript/Guide/Loop_Statements/do...while_Statement") }}</p> diff --git a/files/ja/web/javascript/guide/loop_statements/index.html b/files/ja/web/javascript/guide/loop_statements/index.html new file mode 100644 index 0000000000..54ef32d2c9 --- /dev/null +++ b/files/ja/web/javascript/guide/loop_statements/index.html @@ -0,0 +1,17 @@ +--- +title: ループ文 +slug: Web/JavaScript/Guide/Loop_Statements +--- +<h2 id=".E3.83.AB.E3.83.BC.E3.83.97.E6.96.87" name=".E3.83.AB.E3.83.BC.E3.83.97.E6.96.87">ループ文</h2> +<p>ループは指定した条件が満たされている限り繰り返し実行されるコマンドのセットです。JavaScript は、label はもちろん、for、do while、while といったループ文をサポートしています(label 自体はループ文ではありませんが、これらの文とともに頻繁に使用されます)。さらに、<code>break</code> および <code>continue</code> 文をループ文の中で使うことができます。</p> +<p>さらに <code>for...in</code> 文も文を繰り返し実行しますが、これはオブジェクトの操作に使用します。<a href="/ja/Core_JavaScript_1.5_Guide/Object_Manipulation_Statements" title="ja/Core_JavaScript_1.5_Guide/Object_Manipulation_Statements">オブジェクト操作文</a> をご覧ください。</p> +<p>ループ文は以下のとおりです。</p> +<ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Loop_Statements/for_Statement" title="ja/Core_JavaScript_1.5_Guide/Loop_Statements/for_Statement">for 文</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Loop_Statements/do...while_Statement" title="ja/Core_JavaScript_1.5_Guide/Loop_Statements/do...while_Statement">do...while 文</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Loop_Statements/while_Statement" title="ja/Core_JavaScript_1.5_Guide/Loop_Statements/while_Statement">while 文</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Loop_Statements/label_Statement" title="ja/Core_JavaScript_1.5_Guide/Loop_Statements/label_Statement">label 文</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Loop_Statements/break_Statement" title="ja/Core_JavaScript_1.5_Guide/Loop_Statements/break_Statement">break 文</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Loop_Statements/continue_Statement" title="ja/Core_JavaScript_1.5_Guide/Loop_Statements/continue_Statement">continue 文</a></li> +</ul> +<p>{{ PreviousNext("JavaScript/Guide/Conditional_Statements", "JavaScript/Guide/Loop_Statements/for_Statement") }}</p> diff --git a/files/ja/web/javascript/guide/loop_statements/label_statement/index.html b/files/ja/web/javascript/guide/loop_statements/label_statement/index.html new file mode 100644 index 0000000000..d0b878455b --- /dev/null +++ b/files/ja/web/javascript/guide/loop_statements/label_statement/index.html @@ -0,0 +1,19 @@ +--- +title: label 文 +slug: Web/JavaScript/Guide/Loop_Statements/label_Statement +--- +<h3 id="label_.E6.96.87" name="label_.E6.96.87">label 文</h3> +<p><code>label</code> を使うと、そのプログラムのどこからでも参照できる、識別子を持った文を作ることができます。例えば、ラベルを使用してあるループに名前を付けると、<code>break</code> 文や <code>continue</code> 文を使用してプログラムがループを脱出するべきかそのまま実行を継続するべきかを示すことができます。</p> +<p><code>label</code> 文は次のように使用します。</p> +<pre>label : + statement +</pre> +<p><code>label</code> の値は予約語でなければどんな JavaScript の識別子でも使用できます。ラベルを用いて名前を付ける <code>statement</code> はどんな文でも結構です。</p> +<p><strong>例</strong><br> + この例では <code>markLoop</code> というラベルを用いて while ループに名前を付けています。</p> +<pre>markLoop: +while (theMark == true) + doSomething(); +} +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Loop_Statements/while_Statement", "JavaScript/Guide/Loop_Statements/break_Statement") }}</p> diff --git a/files/ja/web/javascript/guide/loop_statements/while_statement/index.html b/files/ja/web/javascript/guide/loop_statements/while_statement/index.html new file mode 100644 index 0000000000..77fd191f75 --- /dev/null +++ b/files/ja/web/javascript/guide/loop_statements/while_statement/index.html @@ -0,0 +1,35 @@ +--- +title: while 文 +slug: Web/JavaScript/Guide/Loop_Statements/while_Statement +--- +<h3 id="while_.E6.96.87" name="while_.E6.96.87">while 文</h3> +<p><code>while</code> 文は、指定した条件が true に評価される限り文を実行します。<code>while</code> 文は次のように使用します。</p> +<pre class="eval">while (condition) + statement +</pre> +<p>条件が false になるとループ内の <code>statement</code> の実行が停止し、ループの後に続く文にコントロールが渡されます。</p> +<p>ループの <code>statement</code> を実行する前に条件がテストされます。条件が true を返すと <code>statement</code> が実行され、再び条件がテストされます。条件が false を返すと、実行が停止され、<code>while</code> の後に続く文にコントロールが渡されます。</p> +<p>複数の文を実行するにはブロック文 ({ ... }) を用いて文をグループ化してください。</p> +<p><strong>例 1</strong><br> + 次の <code>while</code> ループでは <code>n</code> が 3 より小さい限り反復されます。</p> +<pre class="eval">n = 0; +x = 0; +while (n < 3) { + n++; + x += n; +} +</pre> +<p>それぞれの反復で、ループは <code>n</code> をインクリメントし、その値を <code>x</code> に加えています。その結果、<code>x</code> と <code>n</code> は次の値をとります。</p> +<ul> + <li>第 1 段階終了後:<code>n</code> = 1、<code>x</code> = 1</li> + <li>第 2 段階終了後:<code>n</code> = 2、<code>x</code> = 3</li> + <li>第 3 段階終了後:<code>n</code> = 3、<code>x</code> = 6</li> +</ul> +<p>第 3 段階が完了すると条件 <code>n</code> < 3 が true ではなくなっているため、ループは終了します。</p> +<p><strong>例 2</strong><br> + 無限ループは避けてください。ループの条件が最終的には false になることを確認してください。そうしないとループが終了しなくなります。次の <code>while</code> ループ内の文は永久に実行されます。条件が決して false にならないためです。</p> +<pre class="eval">while (true) { + alert("Hello, world"); +} +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Loop_Statements/do...while_Statement", "JavaScript/Guide/Loop_Statements/label_Statement") }}</p> diff --git a/files/ja/web/javascript/guide/loops_and_iteration/index.html b/files/ja/web/javascript/guide/loops_and_iteration/index.html new file mode 100644 index 0000000000..baf78c7d80 --- /dev/null +++ b/files/ja/web/javascript/guide/loops_and_iteration/index.html @@ -0,0 +1,365 @@ +--- +title: ループと反復処理 +slug: Web/JavaScript/Guide/Loops_and_iteration +tags: + - Guide + - JavaScript + - Loop + - Syntax + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Loops_and_iteration +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</div> + +<p class="summary">ループは繰り返し何かを実行するための簡便な方法を提供します。本章では JavaScript で利用可能な反復処理を行う数々の文を紹介します。</p> + +<p>誰かに話しかけようと、ある方向に <em>X</em> 歩進み、別の方向に <em>Y</em> 進むといった場面を、コンピューター化されたゲームととらえた上で、ループについて考えてみましょう。例えば、「西に 5 歩進む」という概念はループとして、下記のように表現できます :</p> + +<pre class="brush: js notranslate">for (let step = 0; step < 5; step++) { + // 値が 0 から 4 まで計 5 回実行される + console.log('一歩西に歩く'); +} +</pre> + +<p>ループには様々な種類がありますが、本質的にはそれらはすべて同じことをしています : 何らかの行為をある回数繰り返すということです(ただしその回数がゼロということもありえます)。</p> + +<p>様々なループ機構が存在することによって、色々な方法でループの開始点と終了点を決定することができます。あるループの方が別のタイプのループより簡単に目的を果たせる、という状況はたくさんあります。</p> + +<p>JavaScript で提供されるループ文は以下のとおりです :</p> + +<ul> + <li>{{anch("for statement","for 文")}}</li> + <li>{{anch("do...while statement","do...while 文")}}</li> + <li>{{anch("while statement","while 文")}}</li> + <li>{{anch("label statement","label 文")}}</li> + <li>{{anch("break statement","break 文")}}</li> + <li>{{anch("continue statement","continue 文")}}</li> + <li>{{anch("for...in statement","for...in 文")}}</li> + <li>{{anch("for...of statement","for...of 文")}}</li> +</ul> + +<h2 id="for_statement" name="for_statement"><code>for</code> 文</h2> + +<p>{{jsxref("Statements/for","for")}} 文によるループは指定された条件が <code>false</code> と評価されるまで繰り返されます。JavaScript の <code>for</code> ループは Java や C 言語の <code>for</code> ループと同じです。</p> + +<p><code>for</code> 文は以下のような形です :</p> + +<pre class="syntaxbox notranslate">for ([初期化式]; [条件式]; [加算式]) + 文 +</pre> + +<p><code>for</code> ループが実行されるとき、次の処理が行われます :</p> + +<ol> + <li>もしあれば、<code>初期化式</code>が実行されます。この式は通常、1 個またはそれ以上のループカウンターを初期化しますが、この構文ではいかなるレベルの複雑な式を入れることが可能です。初期化式で変数を宣言することもできます。</li> + <li>条件式 条件式が評価されます。<code>条件式</code>の値が <code>true</code> の場合、ループ文が実行されます。<code>条件式</code>の値が <code>false</code> の場合、<code>for</code> ループは終了します。<code>条件式</code>がすべて省略されている場合、条件式は真であると仮定されます。</li> + <li><code>文</code>が実行されます。複数の文を実行するには、それらの文をグループ化するためにブロック文 (<code>{ ... }</code>) を使用します。</li> + <li>もしあれば、更新式 <code>加算式</code>が実行されます。</li> + <li>ステップ 2 に制御が戻ります。</li> +</ol> + +<h3 id="Example" name="Example"><strong>例</strong></h3> + +<p>下の例では、スクロールリスト(複数選択できる {{HTMLElement("select")}} 要素)で選択したオプションの数をカウントする <code>for</code> 文が関数内にあります。<code>for</code> 文が変数 <code>i</code> を宣言しゼロに初期化します。<code>i</code> が <code><select></code> 要素のオプション数未満であることがチェックされると、後続の <code>if</code> 文が実行され、オプションが選択されていれば、ループの各通過後に 1 個ずつ <code>i</code> が加算されます。</p> + +<pre class="brush: html notranslate"><form name="selectForm"> + <p> + <label for="musicTypes">Choose some music types, then click the button below:</label> + <select id="musicTypes" name="musicTypes" multiple="multiple"> + <option selected="selected">R&B</option> + <option>Jazz</option> + <option>Blues</option> + <option>New Age</option> + <option>Classical</option> + <option>Opera</option> + </select> + </p> + <p><input id="btn" type="button" value="How many are selected?" /></p> +</form> + +<script> +function howMany(selectObject) { + let numberSelected = 0; + for (let i = 0; i < selectObject.options.length; i++) { + if (selectObject.options[i].selected) { + numberSelected++; + } + } + return numberSelected; +} + +let btn = document.getElementById('btn'); +btn.addEventListener('click', function() { + alert('Number of options selected: ' + howMany(document.selectForm.musicTypes)); +}); +</script> + +</pre> + +<h2 id="do...while_statement" name="do...while_statement"><code>do...while</code> 文</h2> + +<p>{{jsxref("Statements/do...while","do...while")}} 文は指定された条件が <code>false</code> になるまで繰り返します。</p> + +<p><code>do...while</code> 文は以下のような形です :</p> + +<pre class="syntaxbox notranslate">do + 文 +while (条件式); +</pre> + +<p><em><code>文</code></em>は条件式がチェックされる前に毎回一度実行されます。(複数の文を実行するには、ブロック文 (<code>{ ... }</code>) を使って一つの文にします)。</p> + +<p><code>条件式</code>が <code>true</code> の場合、<code>文</code>が再び実行されます。<code>文</code>の実行終了時に毎回条件がチェックされます。条件が <code>false</code> の場合、実行は停止し、制御は <code>do...while</code> の次の文に渡ります。</p> + +<h3 id="Example_2" name="Example_2"><strong>例</strong></h3> + +<p>次の例では、<code>do</code> ループは少なくとも一度繰り返されます。そして <code>i</code> が 5 未満でなくなる直前まで繰り返しされます。</p> + +<pre class="brush: js notranslate">let i = 0; +do { + i += 1; + console.log(i); +} while (i < 5);</pre> + +<h2 id="while_statement" name="while_statement"><code>while</code> 文</h2> + +<p>{{jsxref("Statements/while","while")}} 文は指定された条件が <code>true</code> に評価される限り文を実行します。<code>while</code> 文は以下のようになります :</p> + +<pre class="syntaxbox notranslate">while (条件式) + 文 +</pre> + +<p><code>条件式</code>が <code>false</code> となる場合、ループ内の<code>文</code>は実行を停止し、ループに続く文に制御が渡されます。</p> + +<p>ループ内の<code>文</code>が実行される<em>前</em>に条件がテストされます。条件が <code>true</code> を返す場合、<code>文</code>は実行され、条件が再びテストされます。条件が <code>false</code> を返す場合、実行は停止し、<code>while</code> の次の文に制御が渡されます。</p> + +<p>複数の文を実行するには、それらの文をグループ化するブロック文 (<code>{ ... }</code>) を使用します。</p> + +<h3 id="Example_1" name="Example_1"><strong>例 1</strong></h3> + +<p>次の例では、<code>while</code> ループは、<code>n</code> が <code>3</code> 未満の場合繰り返されます。:</p> + +<pre class="brush: js notranslate">let n = 0; +let x = 0; +while (n < 3) { + n++; + x += n; +} +</pre> + +<p>各反復で、<code>n</code> がインクリメントされ、その値が <code>x</code> に加算されます。そのため、<code>x</code> と <code>n</code> は以下の値をとります:</p> + +<ul> + <li>1 回目の反復後 : <code>n</code> = <code>1</code>, <code>x</code> = <code>1</code></li> + <li>2 回目の反復後 : <code>n</code> = <code>2</code>, <code>x</code> = <code>3</code></li> + <li>3 回目の反復後 : <code>n</code> = <code>3</code>, <code>x</code> = <code>6</code></li> +</ul> + +<p>3 回目の通過完了後、条件式 <code>n < 3</code> はもはや <code>true</code> ではなくなるため、ループが終了します。</p> + +<h3 id="Example_2_2" name="Example_2_2"><strong>例 2</strong></h3> + +<p>無限ループは避けてください。ループ内の条件が最終的に <code>false</code> になることを確かめるようにしましょう。さもないと、ループは永遠に終了しません。次の <code>while</code> ループ文は、条件が決して <code>false</code> にならないので永遠に実行されます :</p> + +<pre class="example-bad brush: js notranslate">// 無限ループは悪! +while (true) { + console.log('Hello, world!'); +}</pre> + +<h2 id="label_statement" name="label_statement"><code>ラベルつき</code>文</h2> + +<p>{{jsxref("Statements/label","label")}} を使って、プログラム内の他の場所から参照できる識別子を組み込んだ文が作成できます。例えば、ループの識別にラベルを使い、そのプログラムでループを中断するか、実行を継続するかどうかを指定する場合に、ラベルを <code>break</code> 文や <code>continue</code> 文で使用することができます。</p> + +<p>ラベル文の構文は以下のようになります :</p> + +<pre class="syntaxbox notranslate">ラベル : + 文 +</pre> + +<p><code>ラベル</code> の値には、予約語でなければあらゆる JavaScript 識別子を使用できます。ラベルによって識別される<code>文</code>はどんな文でもかまいません。</p> + +<h3 id="Example_3" name="Example_3"><strong>例</strong></h3> + +<p>この例では、ラベル <code>markLoop</code> は <code>while</code> ループを指し示しています。</p> + +<pre class="brush: js notranslate">markLoop: +while (theMark === true) { + doSomething(); +}</pre> + +<h2 id="break_statement" name="break_statement"><code>break</code> 文</h2> + +<p>ループ、<code>switch</code>、ラベル文を使った関連付けを終了させるには {{jsxref("Statements/break","break")}} 文を使います。</p> + +<ul> + <li>ラベルなしで <code>break</code> を使用すると、最も内側の <code>while</code>、<code>do-while</code>、<code>for</code>、<code>switch</code> をただちに終了し、次の文に制御を移します。この場合の <code>break</code> 文の構文は下記のようになります</li> + <li>ラベルつきで <code>break</code> を使用すると、指定したラベルつき文まで終了します。</li> +</ul> + +<p><code>break</code> 文の構文は下記のようになります:</p> + +<pre class="syntaxbox notranslate">break; +break [ラベル]; +</pre> + +<ol> + <li>最初の形では最も内側のループや <code>switch</code> を終了します</li> + <li>2 つ目の形では指定した外側のラベルつき文を終了します。</li> +</ol> + +<h3 id="Example_1_2" name="Example_1_2"><strong>例</strong> <strong>1</strong></h3> + +<p>次の例では、値が <code>theValue</code> である要素のインデックスを探すまで配列の要素を反復します。:</p> + +<pre class="brush: js notranslate">for (let i = 0; i < a.length; i++) { + if (a[i] === theValue) { + break; + } +}</pre> + +<h3 id="Example_2_Breaking_to_a_label" name="Example_2_Breaking_to_a_label"><strong>例 2: </strong>ラベルまでブレーク</h3> + +<pre class="brush: js notranslate">let x = 0; +let z = 0; +labelCancelLoops: while (true) { + console.log('外側のループ: ' + x); + x += 1; + z = 1; + while (true) { + console.log('内側のループ: ' + z); + z += 1; + if (z === 10 && x === 10) { + break labelCancelLoops; + } else if (z === 10) { + break; + } + } +} +</pre> + +<h2 id="continue_statement" name="continue_statement"><code>continue</code> 文</h2> + +<p>{{jsxref("Statements/continue","continue")}} 文は <code>while</code>、<code>do-while</code>、<code>for</code>、<code>label</code> 文を再開する際に使用されます。</p> + +<ul> + <li>ラベルなしで <code>continue</code> を使用すると、その文を囲んでいる最も内側の <code>while</code>、<code>do-while</code>、<code>for</code> 文による現在の反復を終了し、次の反復のループの実行を継続します。<code>break</code> 文とは対照的に、<code>continue</code> は完全にループの実行を終了しません。<code>while</code> ループの場合、条件にジャンプします。<code>for</code> ループでは、<code>加算式</code> にジャンプします。</li> + <li>ラベルとともに <code>continue</code> を使用すると、この動作がそのラベルによって識別されるループ文に対して適用されます。</li> +</ul> + +<p><code>continue</code>文の構文は下記のようになります :</p> + +<pre class="syntaxbox notranslate">continue [ラベル]; +</pre> + +<h3 id="Example_1_3" name="Example_1_3"><strong>例 1</strong></h3> + +<p>次の例では、<code>i</code> の値が 3 のときに実行される <code>continue</code> 文が使用された <code>while</code> ループを示しています。この場合、<code>n</code> の値は <code>1</code>、<code>3</code>、<code>7</code>、<code>12</code> となります。</p> + +<pre class="brush: js notranslate">let i = 0; +let n = 0; +while (i < 5) { + i++; + if (i === 3) { + continue; + } + n += i; + console.log(n); +} +//1,3,7,12 + + +let i = 0; +let n = 0; +while (i < 5) { + i++; + if (i === 3) { + // continue; + } + n += i; + console.log(n); +} +// 1,3,6,10,15 +</pre> + +<h3 id="Example_2_3" name="Example_2_3"><strong>例 2</strong></h3> + +<p>次の例では、<code>checkiandj</code> とラベル付けされた文には <code>checkj</code> とラベル付けされた文が含まれています。<code>continue</code> 文に出会うと、プログラムは <code>checkj</code> の現在の反復を終了し次の反復を開始します。<code>continue</code> に出会うたびに、<code>checkj</code> はその条件が <code>false</code> を返すまで繰り返されます。<code>false</code> が返されると、<code>checkiandj</code> の残りの部分が完了し、その条件が <code>false</code> を返すまで <code>checkiandj</code> が繰り返されます。<code>false</code> が返されると、プログラムは <code>checkiandj</code> に続く文を継続します。</p> + +<p>もし <code>continue</code> が <code>checkiandj</code> のラベルを持っていると、プログラムは <code>checkiandj</code> のラベル文の先頭から継続されます。</p> + +<pre class="brush: js notranslate">let i = 0; +let j = 10; +checkiandj: + while (i < 4) { + console.log(i); + i += 1; + checkj: + while (j > 4) { + console.log(j); + j -= 1; + if ((j % 2) === 0) { + continue checkj; + } + console.log(j + ' is odd.'); + } + console.log('i = ' + i); + console.log('j = ' + j); + }</pre> + +<h2 id="for...in_statement" name="for...in_statement"><code>for...in</code> 文</h2> + +<p>{{jsxref("Statements/for...in","for...in")}} 文はオブジェクトにあるすべての列挙可能なプロパティに対し指定された変数を通して反復処理を行います。それぞれの異なるプロパティに、JavaScript は指定された文を実行します。<code>for...in</code> 文は下記のようになります :</p> + +<pre class="syntaxbox notranslate">for (変数 in オブジェクト) + 文 +</pre> + +<h3 id="Example_4" name="Example_4"><strong>例</strong></h3> + +<p>次の関数は引数としてオブジェクトと、そのオブジェクトの名前を表す文字列を取ります。それからすべてのオブジェクトのプロパティに対して反復し、プロパティ名とその値を表示する文字列を返します。</p> + +<pre class="brush: js notranslate">function dump_props(obj, obj_name) { + let result = ''; + for (let i in obj) { + result += obj_name + '.' + i + ' = ' + obj[i] + '<br>'; + } + result += '<hr>'; + return result; +} +</pre> + +<p><code>make</code> プロパティと <code>model</code> プロパティを持つ <code>car</code> オブジェクトに対し、<code>result</code> は下記のようになります :</p> + +<pre class="brush: js notranslate">car.make = Ford +car.model = Mustang +</pre> + +<h3 id="Arrays" name="Arrays">配列</h3> + +<p>{{jsxref("Array")}} の要素に対して反復処理を行う方法として <strong>for...in</strong> 文を使用したくなるかもしれませんが、これは数値のインデックスに加えてユーザー定義プロパティの名前も返します。</p> + +<p>そのため、配列に対しての反復処理には、数値のインデックスを使い従来の {{jsxref("Statements/for","for")}} ループを使用するほうが良いです。なぜなら、(カスタムプロパティやカスタムメソッドを追加するといった) Array オブジェクトの変更を行った場合、<strong>for...in</strong> 文は配列要素に加えてユーザー定義プロパティに対しても反復処理するからです。</p> + +<h2 id="for...of_statement" name="for...of_statement"><code>for...of</code> 文</h2> + +<p>{{jsxref("Statements/for...of","for...of")}} 文は、<a href="/docs/Web/JavaScript/Guide/iterable">反復可能オブジェクト</a>({{jsxref("Array")}}、{{jsxref("Map")}}、{{jsxref("Set")}}、{{jsxref("functions/arguments","arguments")}} オブジェクトなどを含む)を反復処理するループを生成し、それぞれのプロパティの値に対して実行したい文をともなって作られた反復処理フックを呼び出します。</p> + +<pre class="syntaxbox notranslate">for (<em>変数</em> of <em>オブジェクト</em>) + <em>文</em> +</pre> + +<p>次の例では、<code>for...of</code> ループと {{jsxref("Statements/for...in","for...in")}} ループとの違いを示しています。<code>for...in</code> はプロパティ名に対し反復処理される一方、<code>for...of</code> はプロパティの値に対し反復処理します :</p> + +<pre class="brush:js notranslate">const arr = [3, 5, 7]; +arr.foo = 'hello'; + +for (let i in arr) { + console.log(i); // "0", "1", "2", "foo" が出力される +} + +for (let i of arr) { + console.log(i); // 3, 5, 7 が出力される +} +</pre> + +<p>{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</p> diff --git a/files/ja/web/javascript/guide/meta_programming/index.html b/files/ja/web/javascript/guide/meta_programming/index.html new file mode 100644 index 0000000000..c0b3b18129 --- /dev/null +++ b/files/ja/web/javascript/guide/meta_programming/index.html @@ -0,0 +1,290 @@ +--- +title: メタプログラミング +slug: Web/JavaScript/Guide/Meta_programming +tags: + - ECMAScript 2015 + - Guide + - JavaScript + - Proxy + - Reflect + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Meta_programming +--- +<div>{{jsSidebar("JavaScript Guide")}} {{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}</div> + +<p class="summary">ECMAScript 2015 から、JavaScript には {{jsxref("Proxy")}} オブジェクトと {{jsxref("Reflect")}} オブジェクトがサポートされました。これらは基本的な言語操作(例えば、プロパティ検索、代入、列挙、関数呼び出しなど)に割り込み、動作をカスタマイズできます。この 2 つのオブジェクトのおかげで、JavaScript でメタレベルのプログラミングが行えます。</p> + +<h2 id="Proxies" name="Proxies">Proxy</h2> + +<p>ECMAScript 6 で導入された {{jsxref("Proxy")}} オブジェクトによって、特定の操作に割り込んで動作をカスタマイズできます。</p> + +<p>例えば、オブジェクトのプロパティを取得してみましょう :</p> + +<pre class="brush: js notranslate">let <var>handler</var> = { + get: function(<var>target</var>, name) { + return name in <var>target</var>? <var>target</var>[name] : 42 + } +} + +let p = new Proxy({}, <var>handler</var>) +p.a = 1 +console.log(p.a, p.b) // 1, 42 +</pre> + +<p>この <code>Proxy</code> オブジェクトは <code>target</code>(ここでは空オブジェクト)と <code>get</code> トラップが実装された <code>handler</code> オブジェクトを定義しています。ここで、プロキシとなったオブジェクトは未定義のプロパティを取得しようとした時 <code>undefined</code> を返さず、代わりに数値 42 を返します。</p> + +<p>さらなる使用例がリファレンスの「{{jsxref("Proxy")}}」ページにあります。</p> + +<h3 id="Terminology" name="Terminology">用語集</h3> + +<p>プロキシの機能について話題にする際は、次の用語が使用されます。</p> + +<dl> + <dt>{{jsxref("Global_Objects/Proxy/handler","ハンドラ","","true")}} <span>(handler)</span></dt> + <dd>トラップを入れるためのプレースホルダ用オブジェクト。</dd> + <dt>{{原語併記("トラップ","trap")}}</dt> + <dd>プロパティへのアクセスを提供するメソッド。オペレーティングシステムにおけるトラップの概念と同じようなものです。</dd> + <dt>{{原語併記("ターゲット","target")}}</dt> + <dd>プロキシが仮想化するオブジェクト。これはプロキシのストレージバックエンドとしてしばしば使われます。拡張・設定可能でないプロパティを持つオブジェクトに関する不変条件(変更されないセマンティック、つまりオブジェクトの意味情報)は、このターゲットに対して検証されます。</dd> + <dt>{{原語併記("不変条件","invariant")}}</dt> + <dd>カスタマイズした動作を実装する際、変更されないセマンティックを<strong>不変条件</strong>と呼びます。ハンドラの不変条件に違反した場合、{{jsxref("TypeError")}} が発生します。</dd> +</dl> + +<h2 id="Handlers_and_traps" name="Handlers_and_traps">ハンドラとトラップ</h2> + +<p>次の表は、<code>Proxy</code> オブジェクトに対して利用可能なトラップをまとめたものです。詳細と例についてはリファレンスの<a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler">ハンドラについてのページ</a>をご覧ください。</p> + +<table class="standard-table"> + <thead> + <tr> + <th>ハンドラ / トラップ</th> + <th>割り込みされる処理</th> + <th>不変条件</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}</td> + <td>{{jsxref("Object.getPrototypeOf()")}}<br> + {{jsxref("Reflect.getPrototypeOf()")}}<br> + {{jsxref("Object/proto", "__proto__")}}<br> + {{jsxref("Object.prototype.isPrototypeOf()")}}<br> + {{jsxref("Operators/instanceof", "instanceof")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li><code>getPrototypeOf</code> メソッドはオブジェクトか <code>null</code> を返す必要があります。</li> + <li><code>target</code> が拡張不可の場合、<code>Object.getPrototypeOf(proxy)</code> メソッドは <code>Object.getPrototypeOf(target)</code> と同じ値を返す必要があります。</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}</td> + <td>{{jsxref("Object.setPrototypeOf()")}}<br> + {{jsxref("Reflect.setPrototypeOf()")}}</td> + <td><code>target</code> が拡張不可の場合、<code>prototype</code> パラメータは <code>Object.getPrototypeOf(target)</code> と同じ値である必要があります。</td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}</td> + <td>{{jsxref("Object.isExtensible()")}}<br> + {{jsxref("Reflect.isExtensible()")}}</td> + <td><code>Object.isExtensible(proxy)</code> は <code>Object.isExtensible(target)</code> と同じ値を返す必要があります。</td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}</td> + <td>{{jsxref("Object.preventExtensions()")}}<br> + {{jsxref("Reflect.preventExtensions()")}}</td> + <td> + <p><code>Object.isExtensible(proxy)</code> が <code>false</code> の場合のみ、<code>Object.preventExtensions(proxy)</code> は <code>true</code> を返します。</p> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}</td> + <td>{{jsxref("Object.getOwnPropertyDescriptor()")}}<br> + {{jsxref("Reflect.getOwnPropertyDescriptor()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li><code>getOwnPropertyDescriptor</code> はオブジェクトか <code>undefined</code> のいずれかを返す必要があります。</li> + <li>ターゲットオブジェクトに設定不可の所有プロパティとして存在する場合、そのプロパティについて存在しないと報告することはできません。</li> + <li>拡張不可のターゲットオブジェクトに所有プロパティとして存在する場合、そのプロパティについて存在しないと報告することはできません。</li> + <li>拡張不可のターゲットオブジェクトに所有プロパティとして存在しない場合、そのプロパティについて存在すると報告することはできません。</li> + <li>ターゲットオブジェクトに所有プロパティとして存在しない場合、あるいはターゲットオブジェクトに設定可能な所有プロパティとして存在する場合、そのプロパティについて設定不可と報告することはできません。</li> + <li><code>Object.getOwnPropertyDescriptor(target)</code> の結果は <code>Object.defineProperty</code> を使用してターゲットオブジェクトに適用され、この時に例外は発生しません。</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}</td> + <td>{{jsxref("Object.defineProperty()")}}<br> + {{jsxref("Reflect.defineProperty()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>ターゲットオブジェクトが拡張可能ではない場合、プロパティは追加できません。</li> + <li>ターゲットオブジェクトに設定不可の所有プロパティとして存在しない場合、そのプロパティを追加したり、また設定不可に更新することはできません。</li> + <li>ターゲットオブジェクトに対応する設定可能なプロパティとして存在する場合、そのプロパティを設定不可としてもかまいません。</li> + <li>プロパティが対応するターゲットオブジェクトプロパティを持つ場合、<code>Object.defineProperty(target, prop, descriptor)</code> は例外を発生しません。</li> + <li>strict モードでは、<code>defineProperty</code> ハンドラからの戻り値が <code>false</code> の場合、{{jsxref("TypeError")}} 例外が発生します。</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}</td> + <td>プロパティの照会 :<br> + <code>foo in proxy</code><br> + 継承されたプロパティの照会 :<br> + <code>foo in Object.create(proxy)</code><br> + {{jsxref("Reflect.has()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>ターゲットオブジェクトに設定不可の所有プロパティとして存在する場合、そのプロパティについて存在しないと報告することはできません。</li> + <li>ターゲットオブジェクトの所有プロパティとして存在し、そのターゲットオブジェクトが拡張可能ではない場合、そのプロパティについて存在しないと報告することはできません。</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}</td> + <td>プロパティへのアクセス :<br> + <code>proxy[foo]</code>and <code>proxy.bar</code><br> + 継承されたプロパティアクセス :<br> + <code>Object.create(proxy)[foo]</code><br> + {{jsxref("Reflect.get()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>ターゲットオブジェクトプロパティが書込不可、設定不可のデータプロパティである場合、プロパティに対して報告する値は対応するプロパティと同じ値である必要があります。</li> + <li>対応するターゲットオブジェクトプロパティが、Get 属性に <code>undefined</code> を持つ設定不可のアクセサプロパティである場合、プロパティに対して報告される値を <code>undefined</code> とする必要があります。</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}</td> + <td>プロパティへの代入 :<br> + <code>proxy[foo] = bar</code>, <code>proxy.foo = bar</code><br> + 継承されたプロパティの割り当て :<br> + <code>Object.create(proxy)[foo] = bar</code><br> + {{jsxref("Reflect.set()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>対応するターゲットオブジェクトのプロパティが書込不可、設定不可のデータプロパティである場合、そのプロパティとは違うプロパティ値に変更することはできません。</li> + <li>対応するターゲットオブジェクトプロパティが、Set 属性に <code>undefined</code> を持つ設定不可のアクセサプロパティである場合、プロパティの値を設定することはできません。</li> + <li>strict モードでは、<code>set</code> ハンドラからの戻り値が <code>false</code> の場合、{{jsxref("TypeError")}} 例外が発生します。 + <ul> + </ul> + </li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}</td> + <td>プロパティの削除 :<br> + <code>delete proxy[foo]</code>, <code>delete proxy.foo</code><br> + {{jsxref("Reflect.deleteProperty()")}}</td> + <td>ターゲットオブジェクトに設定不可の所有プロパティとして存在する場合、削除することはできません。</td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/enumerate", "handler.enumerate()")}}</td> + <td>プロパティの列挙 / for...in :<br> + <code>for (var name in proxy) {...}</code><br> + {{jsxref("Reflect.enumerate()")}}</td> + <td><code>enumerate</code> メソッドはオブジェクトを返す必要があります。</td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}</td> + <td>{{jsxref("Object.getOwnPropertyNames()")}}<br> + {{jsxref("Object.getOwnPropertySymbols()")}}<br> + {{jsxref("Object.keys()")}}<br> + {{jsxref("Reflect.ownKeys()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li><code>ownKeys</code> の結果はリストとなります。</li> + <li>出力リストの要素の型は {{jsxref("String")}} か {{jsxref("Symbol")}} のどちらかとなります。</li> + <li>出力リストはターゲットオブジェクト中にあるすべての設定不可な所有プロパティのキーを含める必要があります。</li> + <li>ターゲットオブジェクトが拡張不可の場合、出力リストはターゲットオブジェクト中の所有プロパティのキーをすべて含める必要があり、他の値は含まれません。 + <ul> + </ul> + </li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}</td> + <td><code>proxy(..args)</code><br> + {{jsxref("Function.prototype.apply()")}} and {{jsxref("Function.prototype.call()")}}<br> + {{jsxref("Reflect.apply()")}}</td> + <td><code>handler.apply</code> メソッドに対する不変条件はありません。</td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}</td> + <td><code>new proxy(...args)</code><br> + {{jsxref("Reflect.construct()")}}</td> + <td>出力結果は <code>Object</code> とする必要があります。</td> + </tr> + </tbody> +</table> + +<h2 id="Revocable_Proxy" name="Revocable_Proxy">取り消し可能 <code>Proxy</code></h2> + +<p>{{jsxref("Proxy.revocable()")}} メソッドは取り消し可能な <code>Proxy</code> オブジェクトの生成に使用されます。これにより、プロキシを <code>revoke</code> 関数で取り消し、プロキシの機能を停止することができます。</p> + +<p>その後はプロキシを通じたいかなる操作も {{jsxref("TypeError")}} になります。</p> + +<pre class="brush: js notranslate">let revocable = Proxy.revocable({}, { + get: function(target, name) { + return '[[' + name + ']]' + } +}) +let proxy = revocable.proxy +console.log(proxy.foo) // "[[foo]]" + +revocable.revoke() + +console.log(proxy.foo) // TypeError が発生 +proxy.foo = 1 // TypeError が再び発生 +delete proxy.foo // TypeError がここでも発生 +typeof proxy // "object" が返され, typeof はどんなトラップも引き起こさない +</pre> + +<h2 id="Reflection" name="Reflection">リフレクション</h2> + +<p>{{jsxref("Reflect")}} は JavaScript で割り込み操作を行うメソッドを提供するビルトインオブジェクトです。そのメソッドは {{jsxref("Global_Objects/Proxy/handler","Proxy ハンドラ","","true")}}のメソッドと同じです。</p> + +<p><code>Reflect</code> は関数オブジェクトではありません。</p> + +<p><code>Reflect</code> はハンドラから<code><var>ターゲット</var></code>へのデフォルト操作を転送するのに役立ちます。</p> + +<p>例えば、{{jsxref("Reflect.has()")}} を使えば、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/in"><code>in</code> 演算子</a>を関数として使うことができます :</p> + +<pre class="brush: js notranslate">Reflect.has(Object, 'assign') // true +</pre> + +<h3 id="A_better_apply_function" name="A_better_apply_function">より優れた <code>apply</code> 関数</h3> + +<p>ES5 では、所定の <code>this</code> 値と配列や<a href="/ja/docs/Web/JavaScript/Guide/Indexed_collections#Working_with_array-like_objects">配列様のオブジェクト</a>として提供される <code>arguments</code> を使って関数を呼び出す {{jsxref("Function.prototype.apply()")}} メソッドがよく使われてきました。</p> + +<pre class="brush: js notranslate">Function.prototype.apply.call(Math.floor, undefined, [1.75]) +</pre> + +<p>{{jsxref("Reflect.apply")}} を使えば、より簡潔で分かりやすいものにできます :</p> + +<pre class="brush: js notranslate">Reflect.apply(Math.floor, undefined, [1.75]) +// 1 + +Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]) +// "hello" + +Reflect.apply(RegExp.prototype.exec, /ab/, ['confabulation']).index +// 4 + +Reflect.apply(''.charAt, 'ponies', [3]) +// "i" +</pre> + +<h3 id="Checking_if_property_definition_has_been_successful" name="Checking_if_property_definition_has_been_successful">プロパティ定義の成否チェック</h3> + +<p>成功した時はオブジェクトを返し、失敗した時は {{jsxref("TypeError")}} を発生させる {{jsxref("Object.defineProperty")}} では、プロパティを定義する際に発生するエラーを捉えるのに {{jsxref("Statements/try...catch","try...catch")}} ブロックを使おうとしていたでしょう。{{jsxref("Reflect.defineProperty")}} では成功したかどうかによって真偽値を返すので、ここでは {{jsxref("Statements/if...else","if...else")}} ブロックを使えます :</p> + +<pre class="brush: js notranslate">if (Reflect.defineProperty(target, property, attributes)) { + // 成功した時の処理 +} else { + // 失敗した時の処理 +}</pre> + +<p>{{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}</p> diff --git a/files/ja/web/javascript/guide/modules/index.html b/files/ja/web/javascript/guide/modules/index.html new file mode 100644 index 0000000000..1f976ae67a --- /dev/null +++ b/files/ja/web/javascript/guide/modules/index.html @@ -0,0 +1,457 @@ +--- +title: JavaScript モジュール +slug: Web/JavaScript/Guide/Modules +tags: + - Guide + - JavaScript + - Modules + - export + - impot +translation_of: Web/JavaScript/Guide/Modules +--- +<div>{{jsSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Meta_programming")}}</div> + +<p>本章では、JavaScript のモジュールを使い始めるために必要なことすべてを紹介します。</p> + +<h2 id="A_background_on_modules" name="A_background_on_modules">モジュールの背景</h2> + +<p>JavaScript のプログラムはとても小さいものから始まりました。初期の用途は、必要に応じてウェブページにちょっとした対話的な機能を追加する独立したスクリプト処理がほとんどであったため、大きなスクリプトは通常必要ありませんでした。そして何年かが過ぎ、今や大量の JavaScript を持つ完全なアプリケーションをブラウザーで実行することはもちろん、JavaScript を他のコンテキスト (例えば <a href="/ja/docs/Glossary/Node.js">Node.js</a>) で使うこともあります。</p> + +<p>それゆえ近年は、JavaScript プログラムをモジュールに分割して必要な時にインポートできるような仕組みの提供が検討されるようになってきました。Node.js は長年この機能を提供しており、モジュールの利用を可能にする JavaScript ライブラリーやフレームワークも数多くあります (例えば、他の <a href="https://ja.wikipedia.org/wiki/CommonJS">CommonJS</a> や、<a href="https://github.com/amdjs/amdjs-api/blob/master/AMD.md">AMD</a> ベースのモジュールシステムである <a href="https://requirejs.org/">RequireJS</a> など、そしてより最近では <a href="https://webpack.github.io/">Webpack</a> や <a href="https://babeljs.io/">Babel</a>)。</p> + +<p>良い知らせは、モダンブラウザーがモジュール機能のネイティブサポートを開始していることで、この記事がその全てです。これは良いことです。ブラウザーはモジュールの読み込みを最適化できるので、外部ライブラリーを使用してクライアント側の余分な処理やラウンドトリップを行うよりも効率的にすることができます。</p> + +<h2 id="Browser_support" name="Browser_support">ブラウザーのサポート状況</h2> + +<p>ネイティブの JavaScript モジュール機能は、<code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/import">import</a></code> と <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/export">export</a></code> 文を利用します。これらに対するブラウザーの互換性は次のとおりです。</p> + +<h3 id="import" name="import">import</h3> + +<p>{{Compat("javascript.statements.import")}}</p> + +<h3 id="export" name="export">export</h3> + +<p>{{Compat("javascript.statements.export")}}</p> + +<h2 id="Introducing_an_example" name="Introducing_an_example">使用例の紹介</h2> + +<p>モジュールの使い方を紹介するために、GitHub 上に<a href="https://github.com/mdn/js-examples/tree/master/modules">簡単な使用例</a>を作りました。これらは、ウェブページに {{htmlelement("canvas")}} 要素を追加し、その canvas 上にいくつかの異なる図形 (と、それに関するレポート) を描画する簡単なモジュールの例です。</p> + +<p>このような機能はあまり役に立ちませんが、モジュールの説明が明確になるように意図的に単純にしています。</p> + +<div class="blockIndicator note"> +<p><strong>注意</strong>: 使用例をダウンロードしてローカル実行する場合、ローカルのウェブサーバー上で実行する必要があります。</p> +</div> + +<h2 id="Basic_example_structure" name="Basic_example_structure">構造の基本的な例</h2> + +<p>最初の使用例 (<a href="https://github.com/mdn/js-examples/tree/master/modules/basic-modules">basic-modules</a> を参照) には、次のようなファイル構造があります。</p> + +<pre class="notranslate">index.html +main.js +modules/ + canvas.js + square.js</pre> + +<div class="blockIndicator note"> +<p><strong>注意</strong>: このガイドの使用例のファイル構造は、全て基本的に同一ですので、上記のファイル構造をよく見ることになるでしょう。</p> +</div> + +<p>ディレクトリー modules には、次の 2 つのモジュールがあります。</p> + +<ul> + <li><code>canvas.js</code> — canvas の設定に関する次の関数を持ちます。 + + <ul> + <li><code>create()</code> — 指定された <code>width</code> と <code>height</code> を持つ canvas を、指定された ID を持つラッパー {{htmlelement("div")}} の中に作成し、そのラッパー div 自体を指定された親要素の中に追加します。戻り値は、canvas の 2D コンテキストとラッパーの ID を持つ、オブジェクトです。</li> + <li><code>createReportList()</code> — 順序なしリストを指定されたラッパー要素の中に作成し、これをレポートデータを出力するために使うことができます。戻り値は、リストの ID です。</li> + </ul> + </li> + <li><code>square.js</code> — 次のものを持ちます。 + <ul> + <li><code>name</code> —文字列 'square' を内容とする定数です。</li> + <li><code>draw()</code> — 正方形を、指定された canvas 上に、指定された辺の長さ、位置、色を使って描画します。戻り値は、正方形の辺の長さ、位置、色を持つオブジェクトです。</li> + <li><code>reportArea()</code> — 指定された辺の長さを持つ正方形の面積を、指定されたレポート用のリストに書き出します。</li> + <li><code>reportPerimeter()</code> — 指定された辺の長さを持つ正方形の周囲の長さを、指定されたレポート用のリストに書き出します。</li> + </ul> + </li> +</ul> + +<h2 id="余談_—_.mjs_対_.js">余談 — <code>.mjs</code> 対 <code>.js</code></h2> + +<p>この記事ではモジュールファイルに <code>.js</code> の拡張子を使用していますが、他の記事では <code>.mjs</code> という拡張子が使用されているのを目にすることがあるかもしれません。例えば、<a href="https://v8.dev/features/modules#mjs">V8 のドキュメント</a>ではこれを推奨しています。理由は以下の通りです。</p> + +<ul> + <li>どのファイルがモジュールで、どのファイルが通常の JavaScript であるかを明確にすることができます。</li> + <li>これにより、<a href="https://nodejs.org/api/esm.html#esm_enabling">Node.js</a> のようなランタイムや <a href="https://babeljs.io/docs/en/options#sourcetype">Babel</a> のようなビルドツールで、モジュールファイルがモジュールとして解析されるようになります。</li> +</ul> + +<p>しかし、少なくとも今のところは <code>.js</code> を使い続けることにしました。ブラウザでモジュールを正しく動作させるためには、サーバーが <code>text/javascript</code> などの JavaScript MIME タイプを含む <code>Content-Type</code> ヘッダでモジュールを提供していることを確認する必要があります。そうしないと、"The server responded with a non-JavaScript MIME type" のような厳格な MIME タイプチェックエラーが表示され、ブラウザは JavaScript を実行しません。ほとんどのサーバーでは、<code>.js</code> ファイルにはすでに正しい MIME タイプが設定されていますが、<code>.mjs</code> ファイルにはまだ設定されていません。すでに <code>.mjs</code> ファイルを正しく提供しているサーバーには、<a href="https://pages.github.com/">GitHub Pages</a> や Node.js の <code><a href="https://github.com/http-party/http-server#readme">http-server</a></code> などがあります。</p> + +<p>これは、すでにそのような環境を使用している場合や、今はまだ使用していないが、何をしているか知っていてアクセスできる場合には問題ありません(つまり、<code>.mjs</code> ファイルに正しい <code><a href="https://wiki.developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Type">Content-Type</a></code> を設定するようにサーバーを設定することができます)。しかし、あなたがファイルを提供しているサーバーを制御できない場合には、混乱を引き起こす可能性があります。</p> + +<p>この記事では学習と移植性を考慮して、<code>.js</code> を使用することにしました。</p> + +<p>通常の JavaScript ファイルに <code>.js</code> を使用するのと比較して、モジュールに <code>.mjs</code> を使用することの明確さを本当に重視しているが、上記の問題に直面したくない場合は、開発中に <code>.mjs</code> を使用し、ビルドステップで <code>.js</code> に変換することをおすすめします。</p> + +<p>また、次の点にも注意してください。</p> + +<ul> + <li><a href="https://www.typescriptlang.org/ja/">TypeScript</a> のように、ツールによっては <code>.mjs</code> をサポートしていないものがあります。</li> + <li>モジュールが指し示されているとき、それを示すために <code><script type="module"></code> 属性を使用します。</li> +</ul> + +<h2 id="Exporting_module_features" name="Exporting_module_features">モジュール機能のエクスポート</h2> + +<p>モジュールが持つ機能にアクセスするために最初に必要なことは、そのような機能をエクスポートすることです。これは <code><a href="/ja/docs/Web/JavaScript/Reference/Statements/export">export</a></code> 文を使って行います。</p> + +<p>最も簡単な使い方は、モジュール外部に公開したい項目の前に <code>export</code> をつけることです。</p> + +<pre class="brush: js; notranslate">export const name = 'square'; + +export function draw(ctx, length, x, y, color) { + ctx.fillStyle = color; + ctx.fillRect(x, y, length, length); + + return { + length: length, + x: x, + y: y, + color: color + }; +}</pre> + +<p>エクスポートできるものは、関数、<code>var</code>、<code>let</code>、<code>const</code>、および後で見ることになりますが、クラスです。これらは最上位の階層にある必要があります。例えば、関数内で <code>export</code> を使うことはできません。</p> + +<p>エクスポートしたい全ての項目をエクスポートするより便利な方法は、モジュールファイルの末尾に単一の export 文を追加し、その後にエクスポートしたい機能のカンマ区切りリストを中かっこで囲んで続けることです。例えば次のようにします。</p> + +<pre class="brush: js; notranslate">export { name, draw, reportArea, reportPerimeter };</pre> + +<h2 id="Importing_features_into_your_script" name="Importing_features_into_your_script">スクリプトへの機能のインポート</h2> + +<p>モジュールから何らかの機能をエクスポートした後は、それらを使えるようにするためにスクリプトにインポートする必要があります。その最も単純な方法は次のとおりです。</p> + +<pre class="brush: js; notranslate">import { name, draw, reportArea, reportPerimeter } from './modules/square.js';</pre> + +<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/import">import</a></code> 文の後ろに、中かっこで囲まれたインポートしたい機能のカンマ区切りリストを続け、その後ろに from キーワードと、モジュールファイルへのパスを続けます。このパスは、サイトのルートからの相対パスであり、<code>basic-modules</code> の場合は <code>/js-examples/modules/basic-modules</code> です。</p> + +<p>しかし、この例ではパスの書き方が少し異なっています。「現在の位置」を意味するドット (<code>.</code>) 記法を使っており、その後ろに見つけようとするファイルへのパスを続けています。これは、完全な相対パスを毎回記述するよりも短くてすむためとてもよい方法であり、URL の可搬性もあるため、サイト階層構造の異なる場所に移動させた場合でも動作するでしょう。</p> + +<p>そのため、このようなパスは、</p> + +<pre class="notranslate">/js-examples/modules/basic-modules/modules/square.js</pre> + +<p>このように書けます。</p> + +<pre class="notranslate">./modules/square.js</pre> + +<p>このような書き方の動作している例は <code><a href="https://github.com/mdn/js-examples/blob/master/modules/basic-modules/main.js">main.js</a></code> にあります。</p> + +<div class="blockIndicator note"> +<p><strong>注意</strong>: モジュールシステムの中には、ファイルの拡張子やドットを省略できるものがあります (例えば <code>'/modules/square'</code>)。このような書き方は、ネイティブの JavaScript モジュールでは動作しません。</p> +</div> + +<p>スクリプトへ機能をインポートすると、同じファイル内で定義されているのと同じように使うことができます。次のコードは、<code>main.js</code> でインポートに続く部分です。</p> + +<pre class="brush: js; notranslate">let myCanvas = create('myCanvas', document.body, 480, 320); +let reportList = createReportList(myCanvas.id); + +let square1 = draw(myCanvas.ctx, 50, 50, 100, 'blue'); +reportArea(square1.length, reportList); +reportPerimeter(square1.length, reportList); +</pre> + +<div class="blockIndicator note"> +<p><strong>注: </strong>インポートされた機能はファイル内で利用できますが、エクスポートされた機能の読み取り専用ビューです。インポートされた変数を変更することはできませんが、<code>const</code> と同様にプロパティを変更することはできます。さらに、これらの機能はライブバインディングとしてインポートされます。つまり、<code>const</code> と違ってバインディングを変更できなくても値を変更できるということです。</p> +</div> + +<h2 id="Applying_the_module_to_your_HTML" name="Applying_the_module_to_your_HTML">HTML にモジュールを適用する</h2> + +<p>次に <code>main.js</code> モジュールを HTML ページに適用する必要があります。これは少し重要な点に違いがありますが、通常のスクリプトをページに適用する方法ととてもよく似ています。</p> + +<p>最初に <code>type="module"</code> を {{htmlelement("script")}} 要素に含めることで、そのスクリプトがモジュールであることを宣言します。</p> + +<pre class="brush: js; notranslate"><script type="module" src="main.js"></script></pre> + +<p>また、<code><script></code> 要素の本文内に JavaScript コードを配置することで、モジュールのスクリプトをHTMLファイルに直接埋め込むこともできます。</p> + +<pre class="brush: js notranslate"><script type="module"> + /* ここに JavaScript モジュールコード */ +</script></pre> + +<p>モジュールをインポートする先のスクリプトは、基本的に最上位のモジュールとして動作します。これを無視すると、例えば Firefox の場合は "SyntaxError: import declarations may only appear at top level of a module" (構文エラー: インポート宣言は最上位のモジュールしか使えません) というエラーが発生します。</p> + +<p><code>import</code> と <code>export</code> 文は、モジュールの中でのみ使うことができます。通常のスクリプトの中では使えません。</p> + +<h2 id="Other_differences_between_modules_and_standard_scripts" name="Other_differences_between_modules_and_standard_scripts">モジュールの通常のスクリプトの間のその他の違い</h2> + +<ul> + <li>ローカルでテストしようとするときは注意してください。ローカルから (つまり <code>file://</code> URL を使って) HTML ファイルを読み込もうとすると、JavaScript モジュールのセキュリティ要件のために、CORS エラーが発生します。テストはサーバー経由で行う必要があります。</li> + <li>また、モジュール内部で定義されたスクリプトの動作は、通常のスクリプト内部のものと異なるかもしれません。これは、モジュール内部では自動的に <a href="/ja/docs/Web/JavaScript/Reference/Strict_mode">Strict モード</a> が使われるからです。</li> + <li>モジュールのスクリプトを読み込むときに <code>defer</code> 属性 (<a href="/ja/docs/Web/HTML/Element/script#Attributes"><code><script></code> の属性</a> を参照) を使う必要はありません。モジュールは自動的に遅延実行されます。</li> + <li>モジュールは、複数の <code><script></code> タグで参照されていても一度しか実行されません。</li> + <li>最後ですが重要なこととして明らかにしておきますが、モジュールの機能は単独のスクリプトのスコープにインポートされます。つまり、インポートされた機能はグローバルスコープから利用することはできません。それゆえ、インポートされた機能はインポートしたスクリプトの内部からしかアクセスできず、例えば JavaScript コンソールからはアクセスできません。文法エラーは開発ツール上に表示されますが、使えることを期待するデバッグ技術の中には使えないものがあるでしょう。</li> +</ul> + +<h2 id="Default_exports_versus_named_exports" name="Default_exports_versus_named_exports">デフォルトエクスポートと名前付きエクスポート</h2> + +<p>これまでエクスポートした機能は、<strong>名前付きエクスポート (named export)</strong> というものです。それぞれの項目 (関数、<code>const</code> など) は、エクスポート時にその名前を参照されて、インポート時にもその名前で参照されます。</p> + +<p>エクスポートの種類には、他に<strong>デフォルトエクスポート</strong>と呼ばれるものもあります。これは、モジュールがデフォルトの機能を簡単に持つことができるように設計されたもので、また JavaScript のモジュールが既存の CommonJS や AMD のモジュールシステムと相互運用できるようになります (Json Orendorff による <a href="https://hacks.mozilla.org/2015/08/es6-in-depth-modules/">ES6 In Depth: Modules</a> で上手く説明されています。"Default exports" で検索してみてください)。</p> + +<p>どのように動作するか説明するので、使用例をみてみましょう。basic-modules の <code>square.js</code> に、ランダムな色、大きさ、位置の正方形を描く <code>randomSquare()</code> という関数があります。この関数をデフォルトとしてエクスポートしたいので、ファイルの末尾に次の内容を書きます。</p> + +<pre class="brush: js; notranslate">export default randomSquare;</pre> + +<p>中かっこがないことに注意してください。</p> + +<p>または、<code>export default</code> を関数に追加して、次のように匿名関数のように定義することもできます。</p> + +<pre class="brush: js; notranslate">export default function(ctx) { + ... +}</pre> + +<p><code>main.js</code> では、次のようにしてデフォルトの関数をインポートします。</p> + +<pre class="brush: js; notranslate">import randomSquare from './modules/square.js';</pre> + +<p>インポートの時にも中かっこがないことに注意してください。これは、デフォルトエクスポートはモジュールごとにひとつしか作れず、<code>randomSquare</code> がそれであることがわかっているからです。上記は、基本的に次の簡略表現です。</p> + +<pre class="brush: js; notranslate">import {default as randomSquare} from './modules/square.js';</pre> + +<div class="blockIndicator note"> +<p><strong>注意</strong>: エクスポートされる項目の名前を変更するために使われる as の文法については、以下の {{anch("Renaming imports and exports")}} セクションで説明します。</p> +</div> + +<h2 id="Avoiding_naming_conflicts" name="Avoiding_naming_conflicts">名前の衝突を避ける</h2> + +<p>これまでのところ、キャンバスに図形を描く私たちのモジュールは正常に動作しているようです。しかし、円や三角形など別の図形を描くモジュールを追加しようとしたらどうなるでしょう? そのような図形にも <code>draw()</code> や <code>reportArea()</code> のような関数があるかもしれません。もし同じ名前を持つ異なる関数を同じトップレベルのモジュールファイルにインポートしようとすると、最終的に名前の衝突によるエラーが起きるでしょう。</p> + +<p>幸いなことに、これに対処する方法はいくつかあります。それらについて、次のセクションで見ていきましょう。</p> + +<h2 id="Renaming_imports_and_exports" name="Renaming_imports_and_exports">インポートやエクスポートの名前を変更する</h2> + +<p><code>import</code> 文や <code>export</code> 文の中かっこの中では、キーワード <code>as</code> と新しい名前を使うことで、トップレベルのモジュールでその機能を使うときの名前を変更することができます。</p> + +<p>次の二つの例は、異なる方法ですが、同じことをしています。</p> + +<pre class="brush: js; notranslate">// module.js の内部 +export { + function1 as newFunctionName, + function2 as anotherNewFunctionName +}; + +// main.js の内部 +import { newFunctionName, anotherNewFunctionName } from './modules/module.js';</pre> + +<pre class="brush: js; notranslate">// module.js の内部 +export { function1, function2 }; + +// main.js の内部 +import { function1 as newFunctionName, + function2 as anotherNewFunctionName } from './modules/module.js';</pre> + +<p>実際の例を見てみましょう。<a href="https://github.com/mdn/js-examples/tree/master/modules/renaming">renaming</a> ディレクトリでは、前の使用例と同じモジュールを使っていますが、円や三角形を描画するためのモジュールである <code>circle.js</code> と <code>triangle.js</code> も追加しています。</p> + +<p>それぞれのモジュール内部では、同じ名前を持つ機能がエクスポートされており、それゆえそれぞれの末尾の <code>export</code> 文は次のように同一であることがわかります。</p> + +<pre class="brush: js; notranslate">export { name, draw, reportArea, reportPerimeter };</pre> + +<p>これらを <code>main.js</code> にインポートするために、次のようにするとします。</p> + +<pre class="brush: js; notranslate">import { name, draw, reportArea, reportPerimeter } from './modules/square.js'; +import { name, draw, reportArea, reportPerimeter } from './modules/circle.js'; +import { name, draw, reportArea, reportPerimeter } from './modules/triangle.js';</pre> + +<p>すると、ブラウザーは "SyntaxError: redeclaration of import name" (構文エラー: インポート名の再宣言) (Firefox の場合) のようなエラーを発生させるでしょう。</p> + +<p>そのため、それぞれが固有の名前を持つようにするために、次のようにインポートの名前を変える必要があります。</p> + +<pre class="brush: js; notranslate">import { name as squareName, + draw as drawSquare, + reportArea as reportSquareArea, + reportPerimeter as reportSquarePerimeter } from './modules/square.js'; + +import { name as circleName, + draw as drawCircle, + reportArea as reportCircleArea, + reportPerimeter as reportCirclePerimeter } from './modules/circle.js'; + +import { name as triangleName, + draw as drawTriangle, + reportArea as reportTriangleArea, + reportPerimeter as reportTrianglePerimeter } from './modules/triangle.js';</pre> + +<p>他の方法として、例えば次のようにすることで、モジュールファイル側でこの問題を解決することもできます。</p> + +<pre class="brush: js; notranslate">// in square.js +export { name as squareName, + draw as drawSquare, + reportArea as reportSquareArea, + reportPerimeter as reportSquarePerimeter };</pre> + +<pre class="brush: js; notranslate">// in main.js +import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from './modules/square.js';</pre> + +<p>これも同じように機能します。どちらのスタイルを取るかはあなた次第ですが、モジュール側のコードはそのままにしてインポート側を変更する方が、間違いなく賢明です。これは、制御できないサードパーティーのモジュールからインポートするときには、特に意味があります。</p> + +<h2 id="Creating_a_module_object" name="Creating_a_module_object">モジュールオブジェクトの作成</h2> + +<p>上記のインポート方法は正常に動作しますが、少し使いづらく冗長です。よりよい方法は、モジュール内のそれぞれの機能を、モジュールオブジェクトの中にインポートすることです。その構文は次のとおりです。</p> + +<pre class="brush: js; notranslate">import * as Module from './modules/module.js';</pre> + +<p>これは、<code>module.js</code> の中にある全てのエクスポートを取得して、それらを <code>Module</code> というオブジェクトのメンバーとして利用できるようにすることで、独自の名前空間を持たせるような効果があります。次のようにして使います。</p> + +<pre class="brush: js; notranslate">Module.function1() +Module.function2() +など</pre> + +<p>実際の使用例を見てみましょう。<a href="https://github.com/mdn/js-examples/tree/master/modules/module-objects">module-objects</a> ディレクトリでは、また同じ例を使っていますが、この新しい構文を利用するために書き直されています。モジュール内のエクスポートは、いずれも次の単純な構文を使っています。</p> + +<pre class="brush: js; notranslate">export { name, draw, reportArea, reportPerimeter };</pre> + +<p>一方でインポートは次のようなものです。</p> + +<pre class="brush: js; notranslate">import * as Canvas from './modules/canvas.js'; + +import * as Square from './modules/square.js'; +import * as Circle from './modules/circle.js'; +import * as Triangle from './modules/triangle.js';</pre> + +<p>どの場合も、その指定されたオブジェクト名の配下からモジュールのインポートにアクセスできます。例えば次のようにして使います。</p> + +<pre class="brush: js; notranslate">let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue'); +Square.reportArea(square1.length, reportList); +Square.reportPerimeter(square1.length, reportList);</pre> + +<p>このように (必要な箇所にオブジェクトの名前を含むようにさえすれば) コードは以前と同じように書くことができ、そしてインポートはより簡潔になります。</p> + +<h2 id="Modules_and_classes" name="Modules_and_classes">モジュールとクラス</h2> + +<p>最初の方で触れましたが、クラスをエクスポートしたりインポートすることもできます。これがコード上で名前の衝突を避けるもう一つの方法で、もし自分のモジュールを既にオブジェクト指向のスタイルで書いているのであれば、特に便利です。</p> + +<p><a href="https://github.com/mdn/js-examples/tree/master/modules/classes">classes</a> ディレクトリの中には、私たちの図形を描くモジュールを ES クラスを使って書き直した例があります。例えば <code><a href="https://github.com/mdn/js-examples/blob/master/modules/classes/modules/square.js">square.js</a></code> ファイルでは、次のように全ての機能を一つのクラスの中に持たせています。</p> + +<pre class="brush: js; notranslate">class Square { + constructor(ctx, listId, length, x, y, color) { + ... + } + + draw() { + ... + } + + ... +}</pre> + +<p>そして、次のようにエクスポートします。</p> + +<pre class="brush: js; notranslate">export { Square };</pre> + +<p><code><a href="https://github.com/mdn/js-examples/blob/master/modules/classes/main.js">main.js</a></code> では、これを次のようにインポートします。</p> + +<pre class="brush: js; notranslate">import { Square } from './modules/square.js';</pre> + +<p>そして、正方形を描くために次のようにクラスを使います。</p> + +<pre class="brush: js; notranslate">let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); +square1.draw(); +square1.reportArea(); +square1.reportPerimeter();</pre> + +<h2 id="Aggregating_modules" name="Aggregating_modules">モジュールの集約</h2> + +<p>複数のモジュールをひとつに集約させたいと思うことがあるかもしれません。依存性の階層は複数になることがあり、いくつかあるサブモジュールをひとつの親モジュールにまとめて管理を単純化したいと思うかもしれません。これは、親モジュールで次の形式によるエクスポート構文を使うことで可能です。</p> + +<pre class="brush: js; notranslate">export * from 'x.js' +export { name } from 'x.js'</pre> + +<p>使用例は <a href="https://github.com/mdn/js-examples/tree/master/modules/module-aggregation">module-aggregation</a> ディレクトリを参照してください。この例 (クラスを使った以前の例を元にしています) には、<code>shapes.js</code> というモジュールが追加されています。これは <code>circle.js</code>、<code>square.js</code>、<code>triangle.js</code> の全ての機能をひとつに集約したものです。また、サブモジュールを <code>modules</code> ディレクトリの中にある <code>shapes</code> というサブディレクトリに移動させています。つまり、この例のモジュール構造は次のようなものです。</p> + +<pre class="notranslate">modules/ + canvas.js + shapes.js + shapes/ + circle.js + square.js + triangle.js</pre> + +<p>それぞれのサブモジュールでは、例えば次のような同じ形式のエクスポートが行われています。</p> + +<pre class="brush: js; notranslate">export { Square };</pre> + +<p>その次は集約を行う部分です。<code><a href="https://github.com/mdn/js-examples/blob/master/modules/module-aggregation/modules/shapes.js">shapes.js</a></code> の内部には次のような行があります。</p> + +<pre class="brush: js; notranslate">export { Square } from './shapes/square.js'; +export { Triangle } from './shapes/triangle.js'; +export { Circle } from './shapes/circle.js';</pre> + +<p>これらは、個々のサブモジュールのエクスポートを取得して、それらを <code>shapes.js</code> モジュールから利用できるようにする効果があります。</p> + +<div class="blockIndicator note"> +<p><strong>注意</strong>: <code>shapes.mjs</code> の中で参照されているエクスポートは、基本的にそのファイルを経由して転送されるだけで、ファイルの中には存在しません。そのため、同じファイルの中でそれらを使ったコードを書くことはできません。</p> +</div> + +<p>最後に <code>main.js</code> ファイルでは、全てのモジュールのクラスにアクセスするために、次のインポートを書き換えています。</p> + +<pre class="brush: js; notranslate">import { Square } from './modules/square.js'; +import { Circle } from './modules/circle.js'; +import { Triangle } from './modules/triangle.js';</pre> + +<p>書き換え後は、次のような 1行になります。</p> + +<pre class="brush: js; notranslate">import { Square, Circle, Triangle } from './modules/shapes.js';</pre> + +<h2 id="Dynamic_module_loading" name="Dynamic_module_loading">動的なモジュールの読み込み</h2> + +<p>ブラウザーで利用できる JavaScript モジュールの最新機能は、動的なモジュールの読み込みです。これにより、全てを最初に読み込んでしまうのではなく、必要が生じたときにのみ動的にモジュールを読み込むことができます。これには明らかなパフォーマンス上の利点があります。どのように動作するのか、読んで見てましょう。</p> + +<p>この新しい機能により、<code>import()</code> を関数として実行し、そのときのパラメーターとしてモジュールへのパスを指定することができます。これは次のように <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a> を返し、エクスポートにアクセスできるモジュールオブジェクト ({{anch("Creating a module object")}} を参照) を使って fulfilled 状態になります。</p> + +<pre class="brush: js; notranslate">import('./modules/myModule.js') + .then((module) => { + // モジュールを使って何かをする。 + });</pre> + +<p>例を見てみましょう。<a href="https://github.com/mdn/js-examples/tree/master/modules/dynamic-module-imports">dynamic-module-imports</a> ディレクトリには、以前のクラスの例に基づいた別の使用例があります。しかし、今回は使用例が読み込まれたときにはキャンバスに何も描画しません。その代わり "Circle" (円)、"Square" (正方形)、"Triangle" (三角形) という 3つのボタンを表示し、それらが押されたとき、対応した図形を描くために必要なモジュールを動的に読み込んで使用します。</p> + +<p>この使用例では <code><a href="https://github.com/mdn/js-examples/blob/master/modules/dynamic-module-imports/index.html">index.html</a></code> と <code><a href="https://github.com/mdn/js-examples/blob/master/modules/dynamic-module-imports/main.js">main.js</a></code> のみを変更しており、モジュールのエクスポートは以前と同じままです。</p> + +<p><code>main.js</code> では、それぞれのボタンへの参照を取得するために、次のように <code><a href="/ja/docs/Web/API/Document/querySelector">document.querySelector()</a></code> を使っています。</p> + +<pre class="brush: js; notranslate">let squareBtn = document.querySelector('.square');</pre> + +<p>そしてそれぞれのボタンに、押されたときに関連するモジュールを動的に読み込んで図形を描くためのイベントリスナーを設定します。</p> + +<pre class="brush: js; notranslate">squareBtn.addEventListener('click', () => { + import('./modules/square.js').then((Module) => { + let square1 = new Module.Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); + square1.draw(); + square1.reportArea(); + square1.reportPerimeter(); + }) +});</pre> + +<p>Promise が fullfilled 状態になったときにモジュールオブジェクトを返し、クラスはそのオブジェクトの部分機能であるため、<code>Module.Square( ... )</code> のように <code>Module.</code> を追加したコンストラクターにアクセスする必要があります。</p> + +<h2 id="Troubleshooting" name="Troubleshooting">トラブルシューティング</h2> + +<p>これらは、モジュールの動作に問題があるときに助けになるかもしれないヒントです。もし他にあれば自由にリストに追加してください。</p> + +<ul> + <li>前に説明したので繰り返しになりますが、<code>.mjs</code> ファイルは <code>javascript/esm</code> という MIME タイプ (または JavaScript 互換である <code>application/javascript</code> のような MIME タイプ) で読み込まれる必要があり、そうでなければ厳密な MIME タイプチェックによって "The server responded with a non-JavaScript MIME type" (サーバーが非 JavaScript の MIME タイプを返しました) のようなエラーが発生するでしょう。</li> + <li>HTML ファイルをローカルから (例えば <code>file://</code> の URL を使って) 読み込もうとすると、JavaScript モジュールのセキュリティ要件によって CORS エラーが発生するでしょう。動作検証はサーバー経由で行う必要があります。GitHub は <code>.mjs</code> ファイルを正しい MIME 型で返すため理想的です。</li> + <li><code>.mjs</code> は比較的新しい拡張子であり、OS によってはそれを認識しないか、何か別のものに置き換えようとしてしまうかもしれません。例えば macOS は、通知することなく <code>.mjs</code> ファイルに <code>.js</code> を追加して自動的に拡張子を隠すことがわかりました。そのため、実際にやってくるファイルは全て <code>x.mjs.js</code> のようなものでした。ファイル拡張子を自動的に隠すことをオフにして、<code>.mjs</code> を受け入れるように設定すると問題は無くなります。</li> +</ul> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="https://developers.google.com/web/fundamentals/primers/modules#mjs">Using JavaScript modules on the web</a>, Addy Osmani と Mathias Bynens による</li> + <li><a href="https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/">ES modules: A cartoon deep-dive</a>, Lin Clark による Hacks ブログの投稿</li> + <li><a href="https://hacks.mozilla.org/2015/08/es6-in-depth-modules/">ES6 in Depth: Modules</a>, Jason Orendorff による Hacks ブログの投稿</li> + <li>Axel Rauschmayer の書籍 <a href="http://exploringjs.com/es6/ch_modules.html">Exploring JS: Modules</a></li> +</ul> + +<p>{{Previous("Web/JavaScript/Guide/Meta_programming")}}</p> diff --git a/files/ja/web/javascript/guide/numbers_and_dates/index.html b/files/ja/web/javascript/guide/numbers_and_dates/index.html new file mode 100644 index 0000000000..dbe09c4412 --- /dev/null +++ b/files/ja/web/javascript/guide/numbers_and_dates/index.html @@ -0,0 +1,395 @@ +--- +title: 数値と日付 +slug: Web/JavaScript/Guide/Numbers_and_dates +tags: + - Calculation + - Dates + - FP + - Floating Point + - Floating-Point + - Guide + - Integer + - JavaScript + - Math + - Numbers + - Numeric + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Numbers_and_dates +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}</div> + +<p><span class="seoSummary">本章では、JavaScript で数値と日付の計算を実行するのに使われる概念、オブジェクト、関数について紹介します。</span>これには 10進数、2進数、16 進数数値を含むそれぞれの基数で表された数値を使用することや、数値の幅広い種類の数学的演算を実行するグローバル {{jsxref("Math")}} オブジェクトの使い方も含みます。</p> + +<h2 id="Numbers" name="Numbers">数値</h2> + +<p>JavaScript では、数値はすべて <a href="https://ja.wikipedia.org/wiki/Double-precision_floating-point_format">64 ビット倍精度浮動小数点数のフォーマットである IEEE 754</a> (すなわち、±2<sup>−1022</sup> と ±2<sup>+1023</sup> の間、もしくはおよそ ±10<sup>−308</sup> と ±10<sup>+308</sup> の間の数値、53 ビットの精度による) にしたがって実装されています。±2<sup>53</sup> − 1 までの整数は正確に表現できます。</p> + +<p>浮動小数点数の表現に加えて、数値型は 3 つの記号的な値を持っています。 <code>+</code>{{jsxref("Infinity")}}、<code>-</code>{{jsxref("Infinity")}}、{{jsxref("NaN")}}(非数、not-a-number)です。</p> + +<p>JavaScript に最近巨大な数値を表す {{jsxref("BigInt")}} が実装されました。 <code>BigInt</code> には注意事項があり、例えば、<code>BigInt</code> と {{jsxref("Number")}} の値は同じ演算で混ぜたり比較することができず、<code>BigInt</code> の値を {{jsxref("Math")}} オブジェクトで使用することもできません。</p> + +<p>JavaScript における他のプリミティブ型との関わりについては、<a href="/ja/docs/Web/JavaScript/Data_structures">JavaScript のデータ型とデータ構造</a> もご覧ください。</p> + +<p>4 種類の数値リテラル、10 進数、2 進数、8 進数、16 進数を使用することができます。</p> + +<h3 id="Decimal_numbers" name="Decimal_numbers">10 進数</h3> + +<pre class="brush: js notranslate">1234567890 +42 + +// ゼロを先頭に使用するときは気をつけて: + +0888 // 10 進数として 888 と解析される +0777 // Strict モードでない場合 8 進数として解析される (10 進数の 511 になる) +</pre> + +<p>10 進数リテラルはゼロ (<code>0</code>) から始めて、それ以降に 10 進の桁を続けることが可能ですが、<code>0</code> に続くすべての数値が 8 より小さい場合、その数値は 8 進数として解析されることに注意してください。</p> + +<h3 id="Binary_numbers" name="Binary_numbers">2 進数</h3> + +<p>2 進数の構文では、先行ゼロの後に小文字または大文字の "B" を使います (<code>0b</code> または <code>0B</code>)。<code>0b</code> の後の数値が 0 または 1 ではない場合、 {{jsxref("SyntaxError")}}: "Missing binary digits after 0b"(0b の後に 2 進数の桁がありません) が発生します。</p> + +<pre class="brush: js notranslate">var FLT_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648 +var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040 +var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607</pre> + +<h3 id="Octal_numbers" name="Octal_numbers">8 進数</h3> + +<p>8 進数の構文では、先頭にゼロを使用します。<code>0</code> の後の数値が 0 から 7 の範囲外の場合、数値は 10 進数として解釈されます。</p> + +<pre class="brush: js notranslate">var n = 0755; // 493 +var m = 0644; // 420 +</pre> + +<p>ECMAScript 5 における厳格モードでは上記の 8 進数記法を禁じています。8 進数記法は ECMAScript 5 仕様の一部ではありませんが、すべてのブラウザーで先行ゼロによる 8 進数記法をサポートしており、 <code>0644 === 420</code> や <code>"\045" === "%"</code> となります。ECMAScript 2015 ではまた、先行する <code>0o</code> を使う 8 進数構文をサポートしています。</p> + +<pre class="brush: js notranslate">var a = 0o10; // ES2015: 8 +</pre> + +<h3 id="Hexadecimal_numbers" name="Hexadecimal_numbers">16 進数</h3> + +<p>16 進数の構文では、先行ゼロの後に小文字または大文字の "X" を使います (<code>0x</code> または <code>0X</code>)。0x の後の数値が範囲 (0123456789ABCDEF) 外の場合、 {{jsxref("SyntaxError")}}: "Identifier starts immediately after numeric literal" (数値リテラルの直後に識別子があります) が発生します。</p> + +<pre class="brush: js notranslate">0xFFFFFFFFFFFFFFFFF // 295147905179352830000 +0x123456789ABCDEF // 81985529216486900 +0XA // 10 +</pre> + +<h3 id="Exponentation" name="Exponentation">指数表現</h3> + +<pre class="brush: js notranslate">1E3 // 1000 +2e6 // 2000000 +0.1e2 // 10</pre> + +<h2 id="Number_object" name="Number_object">Number オブジェクト</h2> + +<p>組み込み {{jsxref("Number")}} オブジェクトは最大値、NaN、無限大といった数値定数のプロパティを持っています。これらのプロパティの値は変更できません。下記のように使用します:</p> + +<pre class="brush: js notranslate">var biggestNum = Number.MAX_VALUE; +var smallestNum = Number.MIN_VALUE; +var infiniteNum = Number.POSITIVE_INFINITY; +var negInfiniteNum = Number.NEGATIVE_INFINITY; +var notANum = Number.NaN; +</pre> + +<p>自作した <code>Number</code> オブジェクトのプロパティではなく、上記の定義済み <code>Number</code> オブジェクトのプロパティを常に参照してください。</p> + +<p>次の表は <code>Number</code> オブジェクトのプロパティの要約です。</p> + +<table class="standard-table"> + <caption><code>Number</code> オブジェクトプロパティ</caption> + <thead> + <tr> + <th scope="col">プロパティ</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Number.MAX_VALUE")}}</td> + <td>表現可能な最大値。(<code>±1.7976931348623157e+308</code>)</td> + </tr> + <tr> + <td>{{jsxref("Number.MIN_VALUE")}}</td> + <td>表現可能な最小値。(<code>±5e-324</code>)</td> + </tr> + <tr> + <td>{{jsxref("Number.NaN")}}</td> + <td>非数を表す特別な値。</td> + </tr> + <tr> + <td>{{jsxref("Number.NEGATIVE_INFINITY")}}</td> + <td>負の無限大を表す特別な値。オーバーフローした際に返されます。</td> + </tr> + <tr> + <td>{{jsxref("Number.POSITIVE_INFINITY")}}</td> + <td>正の無限大を表す特別な値。オーバーフローした際に返されます。</td> + </tr> + <tr> + <td>{{jsxref("Number.EPSILON")}}</td> + <td>{{jsxref("Number")}} オブジェクトで表現可能な、ある数とそれよりも大きい最小数との差分値 (計算機イプシロン)。(<code>2.220446049250313e-16</code>)</td> + </tr> + <tr> + <td>{{jsxref("Number.MIN_SAFE_INTEGER")}}</td> + <td>JavaScript で正確に扱える最小の整数値。(−2<sup>53</sup> + 1, or <code>−9007199254740991</code>)</td> + </tr> + <tr> + <td>{{jsxref("Number.MAX_SAFE_INTEGER")}}</td> + <td>JavaScript で正確に扱える最大の整数値。(+2<sup>53</sup> − 1, or <code>+9007199254740991</code>)</td> + </tr> + </tbody> +</table> + +<table class="standard-table"> + <caption><code>Number</code> オブジェクトメソッド</caption> + <thead> + <tr> + <th>メソッド</th> + <th>説明</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Number.parseFloat()")}}</td> + <td>文字列引数を解析し、浮動小数点数を返します。<br> + グローバル関数 {{jsxref("parseFloat", "parseFloat()")}} と同等。</td> + </tr> + <tr> + <td>{{jsxref("Number.parseInt()")}}</td> + <td>文字列引数を解析し、指定された根(基数)の整数を返します。<br> + グローバル関数 {{jsxref("parseInt", "parseInt()")}} と同等。</td> + </tr> + <tr> + <td>{{jsxref("Number.isFinite()")}}</td> + <td>渡された値が有限数であるか否かを判定します。</td> + </tr> + <tr> + <td>{{jsxref("Number.isInteger()")}}</td> + <td>渡された値が整数であるか否かを判定します。</td> + </tr> + <tr> + <td>{{jsxref("Number.isNaN()")}}</td> + <td>渡された値が {{jsxref("Global_Objects/NaN", "NaN")}}(非数)であるか否かを判定します。原型となったグローバル関数 {{jsxref("Global_Objects/isNaN", "isNaN()")}} よりもロバストな(対応能力が強い)バージョン。</td> + </tr> + <tr> + <td>{{jsxref("Number.isSafeInteger()")}}</td> + <td>渡された値が正確に扱える整数であるか否かを判定します。</td> + </tr> + </tbody> +</table> + +<p><code>Number</code> オブジェクトのプロトタイプは様々なフォーマットの <code>Number</code> オブジェクトから情報を取得するメソッドを提供します。次表は <code>Number.prototype</code> のメソッドの要約です。</p> + +<table class="standard-table"> + <caption><code>Number.prototype</code> メソッド</caption> + <thead> + <tr> + <th scope="col">メソッド</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Number.toExponential", "toExponential()")}}</td> + <td>数値の指数表記を表す文字列を返します。</td> + </tr> + <tr> + <td>{{jsxref("Number.toFixed", "toFixed()")}}</td> + <td>数値の固定小数点表記を表す文字列を返します。</td> + </tr> + <tr> + <td>{{jsxref("Number.toPrecision", "toPrecision()")}}</td> + <td>特定の精度の固定小数点表記による数値を表す文字列を返します。</td> + </tr> + </tbody> +</table> + +<h2 id="Math_object" name="Math_object">Math オブジェクト</h2> + +<p>組み込み {{jsxref("Math")}} オブジェクトは数学定数および数学関数のためのプロパティとメソッドを有しています。例えば、<code>Math</code> オブジェクトの <code>PI</code> プロパティは π (3.141...) の値を持ちます。以下のようにアプリケーション内で使用できます。</p> + +<pre class="brush: js notranslate">Math.PI +</pre> + +<p>同様に、標準的な数学関数が <code>Math</code> のメソッドにあります。数学関数には、三角関数、対数、指数、およびその他の関数が含まれます。例えば、三角関数 sin を使用したい場合、下記のように記述します。</p> + +<pre class="brush: js notranslate">Math.sin(1.56) +</pre> + +<p><code>Math</code> のすべての三角関数メソッドはラジアンで引数を取ることに注意してください。</p> + +<p>次表は <code>Math</code> オブジェクトメソッドの要約です。</p> + +<table class="standard-table"> + <caption><code>Math</code> オブジェクトメソッド</caption> + <thead> + <tr> + <th scope="col">メソッド</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Math.abs", "abs()")}}</td> + <td>絶対値。</td> + </tr> + <tr> + <td>{{jsxref("Math.sin", "sin()")}}, {{jsxref("Math.cos", "cos()")}}, {{jsxref("Math.tan", "tan()")}}</td> + <td>標準三角関数。引数はラジアン。</td> + </tr> + <tr> + <td>{{jsxref("Math.asin", "asin()")}}, {{jsxref("Math.acos", "acos()")}}, {{jsxref("Math.atan", "atan()")}}, {{jsxref("Math.atan2", "atan2()")}}</td> + <td>逆三角関数。戻り値はラジアン。</td> + </tr> + <tr> + <td>{{jsxref("Math.sinh", "sinh()")}}, {{jsxref("Math.cosh", "cosh()")}}, {{jsxref("Math.tanh", "tanh()")}}</td> + <td>双曲線三角関数。引数は双曲線角度。</td> + </tr> + <tr> + <td>{{jsxref("Math.asinh", "asinh()")}}, {{jsxref("Math.acosh", "acosh()")}}, {{jsxref("Math.atanh", "atanh()")}}</td> + <td>逆双曲線三角関数。戻り値は双曲線角度。</td> + </tr> + <tr> + <td> + <p>{{jsxref("Math.pow", "pow()")}}, {{jsxref("Math.exp", "exp()")}}, {{jsxref("Math.expm1", "expm1()")}}, {{jsxref("Math.log10", "log10()")}}, {{jsxref("Math.log1p", "log1p()")}}, {{jsxref("Math.log2", "log2()")}}</p> + </td> + <td>指数と対数関数。</td> + </tr> + <tr> + <td>{{jsxref("Math.floor", "floor()")}}, {{jsxref("Math.ceil", "ceil()")}}</td> + <td>引数以下の最大の整数値、引数以上の最小の整数値を返します。</td> + </tr> + <tr> + <td>{{jsxref("Math.min", "min()")}}, {{jsxref("Math.max", "max()")}}</td> + <td>カンマで区切られた数値リストの引数から最小値、最大値をそれぞれ返します。</td> + </tr> + <tr> + <td>{{jsxref("Math.random", "random()")}}</td> + <td>0 から 1 の間のランダムな数値を返します。</td> + </tr> + <tr> + <td>{{jsxref("Math.round", "round()")}}, {{jsxref("Math.fround", "fround()")}}, {{jsxref("Math.trunc", "trunc()")}},</td> + <td>丸めと切り捨て関数。</td> + </tr> + <tr> + <td>{{jsxref("Math.sqrt", "sqrt()")}}, {{jsxref("Math.cbrt", "cbrt()")}}, {{jsxref("Math.hypot", "hypot()")}}</td> + <td>平方根、立方根、引数の二乗の和の平方根を返す。</td> + </tr> + <tr> + <td>{{jsxref("Math.sign", "sign()")}}</td> + <td>数の符号、すなわち数が正、負またはゼロかどうかを返します。</td> + </tr> + <tr> + <td>{{jsxref("Math.clz32", "clz32()")}},<br> + {{jsxref("Math.imul", "imul()")}}</td> + <td>32 ビットのバイナリー表現にした場合の先行ゼロの個数を返す関数。<br> + 2 つの引数を C 言語のように 32 ビット乗算した結果を返す関数。</td> + </tr> + </tbody> +</table> + +<p>他の多くのオブジェクトとは異なり、決して独自の <code>Math</code> オブジェクトを生成しないでください。常にビルトイン <code>Math</code> オブジェクトを使用してください。</p> + +<h2 id="Date_object" name="Date_object">Date オブジェクト</h2> + +<p>JavaScript には日付のためのデータ型がありません。しかし、アプリケーション内で日付を取り扱うための {{jsxref("Date")}} オブジェクトとそのメソッドが利用できます。 <code>Date</code> オブジェクトは日付の設定、取得、操作を行う多数のメソッドを有しています。このオブジェクトはいかなるプロパティも持ちません。</p> + +<p>JavaScript は Java と同じように日付を取り扱います。2 つの言語は同様の日付用メソッドを多く持ち、両方の言語とも、Unix タイムスタンプが 1970 年 1 月 1 日 00:00:00 からの秒の数値であるのと同様に、1970 年 1 月 1 日 00:00:00 からのミリ秒の数値で日付を格納しています。</p> + +<p><code>Date</code> オブジェクトの設定可能範囲は 1970 年 1 月 1 日 UTC 時間 に対し -100,000,000 日から 100,000,000 日までです。</p> + +<p><code>Date</code> オブジェクトは次のように生成します。</p> + +<pre class="brush: js notranslate">var dateObjectName = new Date([parameters]); +</pre> + +<p>ここで <code>dateObjectName</code> は生成される <code>Date</code> オブジェクトの名前です。新しいオブジェクトか、あるいは既存のオブジェクトのプロパティにすることができます。</p> + +<p><code>new</code> キーワードなしで <code>Date</code> を呼び出すと、単に現在の日付と時間を文字列表現にしたものを返します。</p> + +<p>上記構文の <code>parameters</code> は以下のいずれかになります。</p> + +<ul> + <li>パラメータなし: 今日の日時を生成します。例えば、<code>today = new Date();</code></li> + <li>次のような形式による日付を表す文字列: "月 日, 年 時:分:秒." 例えば、<code>var Xmas95 = new Date("December 25, 1995 13:30:00")</code>。時、分、秒を省略した場合、その値はゼロに設定されます。</li> + <li>年、月、日に対応する整数の集合。例えば、<code>var Xmas95 = new Date(1995, 11, 25)</code></li> + <li>年、月、日、時、分、秒に対応する整数の集合。例えば、<code>var Xmas95 = new Date(1995, 11, 25, 9, 30, 0);</code></li> +</ul> + +<h3 id="Methods_of_the_Date_object" name="Methods_of_the_Date_object">Date オブジェクトのメソッド</h3> + +<p>日時を扱う <code>Date</code> オブジェクトのメソッドは下記のカテゴリに分類されます:</p> + +<ul> + <li>"set" メソッド、<code>Date</code> オブジェクト内の日時の値の設定を行うメソッド</li> + <li>"get" メソッド、<code>Date</code> オブジェクトから日時を取得を行うメソッド</li> + <li>"to" メソッド、<code>Date</code> オブジェクトから文字列値を返すメソッド</li> + <li>"parse" と "UTC メソッド、<code>Date</code> 文字列を解析するメソッド</li> +</ul> + +<p>"get" と "set" メソッドを使用して、秒、分、時、日、曜日、月、年をそれぞれ取得、設定できます。曜日を返す <code>getDay</code> メソッドはありますが、対応する <code>setDay</code> メソッドはありません。というのも、曜日は自動的に設定されるからです。これらのメソッドはそれぞれの値を表すのに下記の整数値を使用します:</p> + +<ul> + <li>秒と分: 0 〜 59</li> + <li>時: 0 〜 23</li> + <li>曜日: 0 (日曜日) 〜 6 (土曜日)</li> + <li>日: 1 〜 31 (日)</li> + <li>月: 0 (1 月) 〜 11 (12 月)</li> + <li>年: 1900 年以降の年</li> +</ul> + +<p>例えば、次の日付を定義してみます。</p> + +<pre class="brush: js notranslate">var Xmas95 = new Date('December 25, 1995'); +</pre> + +<p>すると、<code>Xmas95.getMonth()</code> は 11 を返し、<code>Xmas95.getFullYear()</code> は 1995 を返します。</p> + +<p><code>getTime</code> と <code>setTime</code> メソッドは日付を比較するのに便利です。<code>getTime</code> メソッドは <code>Date</code> オブジェクトに対して January 1, 1970, 00:00:00 からのミリ秒の数値を返します。</p> + +<p>例えば、次のコードでは今年に残された日数を表示します。:</p> + +<pre class="brush: js notranslate">var today = new Date(); +var endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // 月日を設定 +endYear.setFullYear(today.getFullYear()); // 今年の年を設定 +var msPerDay = 24 * 60 * 60 * 1000; // 一日をミリ秒に換算 +var daysLeft = (endYear.getTime() - today.getTime()) / msPerDay; +var daysLeft = Math.round(daysLeft); // 今年の残り日数を返す +</pre> + +<p>この例では、今日の日時を含む <code>today</code> と名付けられた <code>Date</code> オブジェクトを生成します。それから、<code>endYear</code> と名付けられた <code>Date</code> オブジェクトを生成し、年を今年に設定します。そして、1日あたりのミリ秒値を使って、<code>today</code> と <code>endYear</code> 間の日数を計算する際に <code>getTime</code> を使用し、そして日数に丸めます。</p> + +<p><code>parse</code> メソッドは日付文字列から既存の <code>Date</code> オブジェクトに値を割り当てるのに便利です。例えば、次のコードは <code>parse</code> と <code>setTime</code> を使用し、日付の値を <code>IPOdate</code> オブジェクトに割り当てます:</p> + +<pre class="brush: js notranslate">var IPOdate = new Date(); +IPOdate.setTime(Date.parse('Aug 9, 1995')); +</pre> + +<h3 id="Example" name="Example">例</h3> + +<p>次の例では、<code>JSClock()</code> 関数がデジタル時計の形式で時刻を返します。</p> + +<pre class="brush: js notranslate">function JSClock() { + var time = new Date(); + var hour = time.getHours(); + var minute = time.getMinutes(); + var second = time.getSeconds(); + var temp = '' + ((hour > 12) ? hour - 12 : hour); + if (hour == 0) + temp = '12'; + temp += ((minute < 10) ? ':0' : ':') + minute; + temp += ((second < 10) ? ':0' : ':') + second; + temp += (hour >= 12) ? ' P.M.' : ' A.M.'; + return temp; +} +</pre> + +<p><code>JSClock</code> 関数は、はじめに <code>time</code> という名前の新しい <code>Date</code> オブジェクトを生成します。引数が与えられていないため、time は現在の日付と時刻で生成されます。次に、<code>getHours</code> および <code>getMinutes</code>、<code>getSeconds</code> メソッドを呼び出して、現在の時、分、秒を <code>hour</code>、<code>minute</code>、<code>second</code> に代入します。</p> + +<p>続く 4 つの式は、時刻を基にした文字列値を組み立てます。最初の式は <code>temp</code> 変数を生成し、それに条件式を用いて値を代入します。<code>hour</code> が 12 よりも大きい場合は (<code>hour - 12</code>)、そうでない場合は単に hour を代入します。hour が 0 の場合は 12 になります。</p> + +<p>次の式は、<code>minute</code> 値を <code>temp</code> に追加します。<code>minute</code> の値が 10 よりも小さい場合、条件式により先行ゼロの文字が追加されます。そうでない場合は区切りのコロン文字を追加します。そして秒の値を同じ方法で <code>temp</code> に追加します。</p> + +<p>最後の条件式は、<code>hour</code> が 12 以上の場合、"P.M." を <code>temp</code> に追加します。そうでない場合は "A.M." を <code>temp</code> に追加します。</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}</p> diff --git a/files/ja/web/javascript/guide/object_manipulation_statements/index.html b/files/ja/web/javascript/guide/object_manipulation_statements/index.html new file mode 100644 index 0000000000..ddf781e031 --- /dev/null +++ b/files/ja/web/javascript/guide/object_manipulation_statements/index.html @@ -0,0 +1,51 @@ +--- +title: Object Manipulation Statements +slug: Web/JavaScript/Guide/Object_Manipulation_Statements +--- +<h3 id=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E6.93.8D.E4.BD.9C.E6.96.87" name=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E6.93.8D.E4.BD.9C.E6.96.87">オブジェクト操作文</h3> +<p>JavaScript はオブジェクトの操作に <code>for...in</code>、<code>for each...in</code> および <code>with</code> 文を使用します。</p> +<h4 id="for...in_.E6.96.87" name="for...in_.E6.96.87">for...in 文</h4> +<p><a href="/ja/Core_JavaScript_1.5_Reference/Statements/for...in" title="ja/Core_JavaScript_1.5_Reference/Statements/for...in"><code>for...in</code></a> 文は指定した変数をオブジェクトの全プロパティに対して反復します。それぞれのプロパティに対して JavaScript は指定した文を実行します。<code>for...in</code> 文は次のように使用します。</p> +<pre>for (variable in object) { + statements +} +</pre> +<p><strong>例</strong><br> + 次の関数は、あるオブジェクトとそのオブジェクトの名前を引数にとります。そしてそのオブジェクトの全プロパティに対して反復し、プロパティ名とその値のリストにした文字列を返します。</p> +<pre>function dump_props(obj, obj_name) { + var result = ""; + for (var i in obj) { + result += obj_name + "." + i + " = " + obj[i] + "<br>"; + } + result += "<hr>"; + return result; +} +</pre> +<p><code>make</code> および <code>model</code> というプロパティを持つ <code>car</code> というオブジェクトでは次のような結果が得られます。</p> +<pre class="eval">car.make = Ford +car.model = Mustang +</pre> +<p><strong>配列</strong><br> + <a href="/ja/Core_JavaScript_1.5_Reference/Global_Objects/Array" title="ja/Core_JavaScript_1.5_Reference/Global_Objects/Array">Array</a> の要素に対して反復する方法としてこれを用いることは魅力的かもしれませんが、<strong>for...in</strong> 文はその配列の要素に加えてユーザ定義プロパティに対して繰り返すため、独自のプロパティやメソッドを追加するなどして Array オブジェクトに変更を加えると <strong>for...in</strong> 文は数値のインデックスに加えてユーザ定義プロパティの名前を返します。したがって、配列に対して反復したいときには数値のインデックスを用いた従来の <a href="/ja/Core_JavaScript_1.5_Reference/Statements/for" title="ja/Core_JavaScript_1.5_Reference/Statements/for">for</a> ループを使用したほうがいいでしょう。</p> +<h4 id="for_each...in_.E6.96.87" name="for_each...in_.E6.96.87">for each...in 文</h4> +<p><a href="/ja/Core_JavaScript_1.5_Reference/Statements/for_each...in" title="ja/Core_JavaScript_1.5_Reference/Statements/for_each...in"><code>for each...in</code></a> は <a href="/ja/New_in_JavaScript_1.6" title="ja/New_in_JavaScript_1.6">JavaScript 1.6</a> で導入されるループ文です。これは <code>for...in</code> に似ていますが、オブジェクトのプロパティの名前ではなく、プロパティの値に対して反復します。</p> +<h4 id="with_.E6.96.87" name="with_.E6.96.87">with 文</h4> +<p><a href="/ja/Core_JavaScript_1.5_Reference/Statements/with" title="ja/Core_JavaScript_1.5_Reference/Statements/with"><code>with</code></a> 文はデフォルトのオブジェクトについて文のセットを実行します。JavaScript はその文のセットにおいて非修飾名を検索し、その名前がデフォルトのオブジェクトのプロパティであるかを決定します。非修飾名がプロパティにマッチすると、そのプロパティがその文で使われます。そうでない場合はローカル変数かグローバル変数が使われます。</p> +<p><code>with</code> 文は次のように使用します。</p> +<pre>with (object) { + statements +} +</pre> +<p><strong>例</strong><br> + 次の <code>with</code> 文では <code>Math</code> オブジェクトがデフォルトのオブジェクトに指定されています。<code>with</code> 文内の文は <code>PI</code> プロパティや <code>cos</code> および <code>sin</code> メソッドを参照していますが、オブジェクトは指定していません。JavaScript はこれらの参照は <code>Math</code> オブジェクトへのものであると想定します。</p> +<pre>var a, x, y; +var r = 10; +with (Math) { + a = PI * r * r; + x = r * cos(PI); + y = r * sin(PI/2); +} +</pre> +<p>注意:<code>with</code> 文を使うことでプログラムをより簡潔にすることができますが、<code>with</code> の不適切な使用はプログラムを大幅にスローダウンさせることに繋がります。<a href="/ja/Core_JavaScript_1.5_Reference/Statements/with" title="ja/Core_JavaScript_1.5_Reference/Statements/with">Core JavaScript 1.5 Reference:Statements:with</a> を参照してください。</p> + +<p>{{ PreviousNext("JavaScript/Guide/Loop_Statements/continue_Statement", "JavaScript/Guide/Comments") }}</p> diff --git a/files/ja/web/javascript/guide/objects_and_properties/index.html b/files/ja/web/javascript/guide/objects_and_properties/index.html new file mode 100644 index 0000000000..f2679c1d00 --- /dev/null +++ b/files/ja/web/javascript/guide/objects_and_properties/index.html @@ -0,0 +1,32 @@ +--- +title: オブジェクトとプロパティ +slug: Web/JavaScript/Guide/Objects_and_Properties +--- +<h3 id=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.A8.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3" name=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.A8.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3">オブジェクトとプロパティ</h3> +<p>JavaScript のオブジェクトには、それに結びつけられたプロパティがあります。簡単な記法でオブジェクトのプロパティにアクセスできます。</p> +<pre>objectName.propertyName +</pre> +<p>オブジェクト名もプロパティ名も大文字と小文字を区別します。プロパティの定義は、そのプロパティに値を代入することで行います。例えば、<code>myCar</code> という名前のオブジェクトがあるとします(今回はオブジェクトが既に存在していると仮定)。次のようにして、そのオブジェクトに <code>make</code>、<code>model</code>、<code>year</code> という名前のプロパティをそれぞれ作成することができます。</p> +<pre>myCar.make = "Ford"; +myCar.model = "Mustang"; +myCar.year = 1969; +</pre> +<p>配列はある単一の変数名に結びつけられた値の順序集合です。JavaScript におけるプロパティと配列は密接に関連しています。事実、それらは同一のデータ構造への異なるインタフェースなのです。そのため、例えば次のようにして <code>myCar</code> オブジェクトのプロパティにアクセスすることができます。</p> +<pre>myCar["make"] = "Ford"; +myCar["model"] = "Mustang"; +myCar["year"] = 1969; +</pre> +<p>この手の配列は<em>連想配列</em>として知られています。それぞれのインデックスの要素が文字列にも結びつけられているからです。これがどう動作するかというと、次の関数は引数としてオブジェクトとそのオブジェクトの名前を渡すとオブジェクトのプロパティを表示します。</p> +<pre>function show_props(obj, obj_name) { + var result = ""; + for (var i in obj) + result += obj_name + "." + i + " = " + obj[i] + "\n"; + return result; +} +</pre> +<p>関数 <code>show_props(myCar, "myCar")</code> を呼び出すと以下の結果が返されます。</p> +<pre>myCar.make = Ford +myCar.model = Mustang +myCar.year = 1969 +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Predefined_Functions/escape_and_unescape_Functions", "JavaScript/Guide/Creating_New_Objects") }}</p> diff --git a/files/ja/web/javascript/guide/obsolete_pages/index.html b/files/ja/web/javascript/guide/obsolete_pages/index.html new file mode 100644 index 0000000000..7594f13fd9 --- /dev/null +++ b/files/ja/web/javascript/guide/obsolete_pages/index.html @@ -0,0 +1,9 @@ +--- +title: Obsolete Pages +slug: Web/JavaScript/Guide/Obsolete_Pages +translation_of: Web/JavaScript/Guide +--- +<p>This is a list of pages that have been merged into chapters (in alphabetical order):</p> + + +<div>{{tree}}</div> diff --git a/files/ja/web/javascript/guide/obsolete_pages/predefined_core_objects/function_object/index.html b/files/ja/web/javascript/guide/obsolete_pages/predefined_core_objects/function_object/index.html new file mode 100644 index 0000000000..79c30b670a --- /dev/null +++ b/files/ja/web/javascript/guide/obsolete_pages/predefined_core_objects/function_object/index.html @@ -0,0 +1,44 @@ +--- +title: Function Object +slug: Web/JavaScript/Guide/Obsolete_Pages/Predefined_Core_Objects/Function_Object +--- +<p> </p> +<h3 id="Function_.E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88" name="Function_.E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88">Function オブジェクト</h3> +<p>定義済みの <code>Function</code> オブジェクトは、関数としてコンパイルさせたい JavaScript コードの文字列を指定します。</p> +<p><code>Function</code> オブジェクトを作成するには次のようにします。</p> +<pre>functionObjectName = new Function ([arg1, arg2, ... argn], functionBody) +</pre> +<p><code>functionObjectName</code> は変数名または既存のオブジェクトのプロパティ名です。オブジェクトに小文字のイベントハンドラ名を続けて、<code>window.onerror</code> のようにして指定することもできます。</p> +<p><code>arg1</code>, <code>arg2</code>, ... <code>argn</code> は関数が仮引数名として使用する引数です。それぞれが JavaScript の識別子として妥当な文字列である必要があります。例えば、"x" や "theForm" などです。</p> +<p><code>functionBody</code> は関数の本体としてコンパイルさせたい JavaScript コードを表す文字列です。</p> +<p><code>Function</code> オブジェクトはそれが使用されるたびに評価されます。これは関数を宣言し、それをコード内で呼び出す方法よりも非効率的です。宣言された関数はコンパイルされるからです。</p> +<p>ここで説明した関数の定義方法に加えて、<code>function</code> 文と関数式を用いることもできます。詳しくは <a href="/ja/Core_JavaScript_1.5_Reference" title="ja/Core_JavaScript_1.5_Reference">コア JavaScript 1.5 リファレンス</a> を参照してください。</p> +<p>次のコードは関数を変数 <code>setBGColor</code> に代入します。この関数は開いている文書の背景色をセットします。</p> +<pre>var setBGColor = new Function("document.bgColor='antiquewhite'") +</pre> +<p><code>Function</code> オブジェクトを呼び出すには、それがあたかも関数であるかのように変数名を指定すればいいのです。次のコードは <code>setBGColor</code> 変数で指定された関数を実行します。</p> +<pre>var colorChoice="antiquewhite" +if (colorChoice=="antiquewhite") {setBGColor()} +</pre> +<p>次のどちらかの方法を使用することでイベントハンドラに関数を代入することができます。</p> +<pre>1. document.form1.colorButton.onclick=setBGColor +2. <INPUT NAME="colorButton" TYPE="button" + VALUE="Change background color" + onClick="setBGColor()"> +</pre> +<p>上記の変数 <code>setBGColor</code> を作成することは次の関数を宣言することと同じようなことです。</p> +<pre>function setBGColor() { + document.bgColor='antiquewhite' +} +</pre> +<p>関数を変数に代入することは関数を宣言することと似ていますが、異なる点もあります。</p> +<ul> + <li><code>var setBGColor = new Function("...")</code> のようにして関数を変数に代入すると、<code>setBGColor</code> は <code>new Function()</code> を用いて作成した関数への参照がその値であるような変数になります。</li> + <li><code>function setBGColor() {...}</code> のようにして関数を作成すると、<code>setBGColor</code> は変数ではなく関数の名前になります。</li> +</ul> +<p>関数を関数の中に入れ子にすることができます。内側の関数は外側の関数に対してプライベートになります。</p> +<ul> + <li>内側の関数には外側の関数の文からしかアクセスできません。</li> + <li>内側の関数は外側の関数の引数や変数を使用できます。外側の関数は内側の関数の引数や変数を使用できません。</li> +</ul> +<p>{{ PreviousNext("Core_JavaScript_1.5_Guide:Predefined_Core_Objects:Date_Object", "Core_JavaScript_1.5_Guide:Predefined_Core_Objects:Math_Object") }}</p> diff --git a/files/ja/web/javascript/guide/operators/arithmetic_operators/index.html b/files/ja/web/javascript/guide/operators/arithmetic_operators/index.html new file mode 100644 index 0000000000..4aa9662292 --- /dev/null +++ b/files/ja/web/javascript/guide/operators/arithmetic_operators/index.html @@ -0,0 +1,47 @@ +--- +title: 算術演算子 +slug: Web/JavaScript/Guide/Operators/Arithmetic_Operators +--- +<h3 id=".E7.AE.97.E8.A1.93.E6.BC.94.E7.AE.97.E5.AD.90" name=".E7.AE.97.E8.A1.93.E6.BC.94.E7.AE.97.E5.AD.90">算術演算子</h3> +<p>算術演算子は、そのオペランドに数値(リテラルか変数)をとり、1 つの数値を返します。標準的な算術演算子は、加算 (+)、減算 (-)、乗算 (*)、除算 (/) です。これらの演算子は他のほとんどのプログラミング言語と同じように機能しますが、そのときの数値は、浮動小数点数として扱われます(0 で除算した結果は、<a href="/ja/Core_JavaScript_1.5_Reference/Global_Properties/NaN" title="ja/Core_JavaScript_1.5_Reference/Global_Properties/NaN"><code>NaN</code></a> になることにも注意してください)。</p> +<pre>1 / 2 // JavaScript では 0.5 を返す +1 / 2 // Java では 0 を返す(どちらの数も浮動小数点数として明記されていない) + +1.0 / 2.0 // JavaScript でも Java でも 0.5 を返す +</pre> +<p>さらに、JavaScript では以下の表で示された算術演算子も使用できます。</p> +<table class="fullwidth-table"> + <tbody> + <tr> + <th>演算子</th> + <th>説明</th> + <th>例</th> + </tr> + <tr> + <td>%<br> + (モジュロ)</td> + <td>2 項演算子。2 つのオペランドで除算したときの整数の余りを返す。</td> + <td>12 % 5 は 2 を返す。</td> + </tr> + <tr> + <td>++<br> + (インクリメント)</td> + <td>単項演算子。オペランドに 1 を加える。前置演算子 (++x) を使った場合、オペランドに 1 を加えた後にその値を返す。後置演算子 (x++) を使った場合、オペランドに 1 を加える前にその値を返す。</td> + <td><code>x</code> が 3 のとき、<code>++x</code> は <code>x</code> に 4 をセットし、4 を返す。一方、<code>x++</code> は <code>x</code> に 4 をセットし、3 を返す。</td> + </tr> + <tr> + <td>--<br> + (デクリメント)</td> + <td>単項演算子。オペランドから 1 を引く。戻り値はインクリメント演算子のものと同様。</td> + <td><code>x</code> が 3 のとき、<code>--x</code> は <code>x</code> に 2 をセットし、2 を返す。一方、<code>x--</code> は <code>x</code> に 2 をセットし、3 を返す。</td> + </tr> + <tr> + <td>-<br> + (符号反転)</td> + <td>単項演算子。オペランドの符号を反転してその値を返す。</td> + <td><code>x</code> が 3 のとき、<code>-x</code> は -3 を返す。</td> + </tr> + </tbody> +</table> +<p><small><strong>表 3.4:算術演算子</strong></small></p> +<p>{{ PreviousNext("JavaScript/Guide/Operators/Comparison_Operators", "JavaScript/Guide/Operators/Bitwise_Operators") }}</p> diff --git a/files/ja/web/javascript/guide/operators/assignment_operators/index.html b/files/ja/web/javascript/guide/operators/assignment_operators/index.html new file mode 100644 index 0000000000..88a0b0beb7 --- /dev/null +++ b/files/ja/web/javascript/guide/operators/assignment_operators/index.html @@ -0,0 +1,61 @@ +--- +title: 代入演算子 +slug: Web/JavaScript/Guide/Operators/Assignment_Operators +--- +<h3 id=".E4.BB.A3.E5.85.A5.E6.BC.94.E7.AE.97.E5.AD.90" name=".E4.BB.A3.E5.85.A5.E6.BC.94.E7.AE.97.E5.AD.90">代入演算子</h3> +<p>代入演算子は、右のオペランドの値に基づいた値を左のオペランドに代入します。基本的な代入演算子はイコール (=) ですが、これは右のオペランドの値を左のオペランドに代入します。すなわち、x = y では y の値を x に代入します。</p> +<p>他の代入演算子は標準的な演算をするための短縮表記があります。次の表でそれを示します。</p> +<table class="fullwidth-table"> + <tbody> + <tr> + <th>短縮表記した演算子</th> + <th>意味</th> + </tr> + <tr> + <td>x += y</td> + <td>x = x + y</td> + </tr> + <tr> + <td>x -= y</td> + <td>x = x - y</td> + </tr> + <tr> + <td>x *= y</td> + <td>x = x * y</td> + </tr> + <tr> + <td>x /= y</td> + <td>x = x / y</td> + </tr> + <tr> + <td>x %= y</td> + <td>x = x % y</td> + </tr> + <tr> + <td>x <<= y</td> + <td>x = x << y</td> + </tr> + <tr> + <td>x >>= y</td> + <td>x = x >> y</td> + </tr> + <tr> + <td>x >>>= y</td> + <td>x = x >>> y</td> + </tr> + <tr> + <td>x &= y</td> + <td>x = x & y</td> + </tr> + <tr> + <td>x ^= y</td> + <td>x = x ^ y</td> + </tr> + <tr> + <td>x |= y</td> + <td>x = x | y</td> + </tr> + </tbody> +</table> +<p><small><strong>表 3.2:代入演算子</strong></small></p> +<p>{{ PreviousNext("JavaScript/Guide/Operators", "JavaScript/Guide/Operators/Comparison_Operators") }}</p> diff --git a/files/ja/web/javascript/guide/operators/comparison_operators/index.html b/files/ja/web/javascript/guide/operators/comparison_operators/index.html new file mode 100644 index 0000000000..182802bb5a --- /dev/null +++ b/files/ja/web/javascript/guide/operators/comparison_operators/index.html @@ -0,0 +1,67 @@ +--- +title: 比較演算子 +slug: Web/JavaScript/Guide/Operators/Comparison_Operators +--- +<h3 id=".E6.AF.94.E8.BC.83.E6.BC.94.E7.AE.97.E5.AD.90" name=".E6.AF.94.E8.BC.83.E6.BC.94.E7.AE.97.E5.AD.90">比較演算子</h3> +<p><span class="comment">This seems to me kind of poorly explained, mostly the diference betwen "==" and "==="...</span> 比較演算子は、オペランドを比較し、比較結果に基づいた論理値を返します。オペランドには数値、文字列、論理値、オブジェクトが使用できます。文字列は、Unicode 値を用いて標準的な辞書順に基づいて比較されます。ほとんどの場合、2 つのオペランドが異なる型ならば JavaScript はそのオペランドを比較に適した型に変換しようとします(このルールの唯一の例外は <code>===</code> および <code>!==</code> であり、これらは厳密に等値か否かを判断し、等値性をチェックする前にオペランドを適合する型に変換するということはありません)。これは一般に数値の比較が実行されることになります。次の表では比較演算子について説明します。次のコードで考えます。</p> +<pre class="eval">var var1 = 3, var2 = 4; +</pre> +<table class="fullwidth-table"> + <tbody> + <tr> + <th>演算子</th> + <th>説明</th> + <th>true を返す例</th> + </tr> + <tr> + <td>等しい (==)</td> + <td>オペランドが等しい場合に true を返す。</td> + <td><code>3 == var1</code><br> + <p><code>"3" == var1</code></p> + <code>3 == '3'</code></td> + </tr> + <tr> + <td>等しくない (!=)</td> + <td>オペランドが等しくない場合に true を返す。</td> + <td><code>var1 != 4<br> + var2 != "3"</code></td> + </tr> + <tr> + <td>厳密に等しい (===)</td> + <td>オペランドが等しく、かつ同じ型である場合に true を返す。</td> + <td><code>3 === var1</code></td> + </tr> + <tr> + <td>厳密には等しくない (!==)</td> + <td>オペランドが等しくなく、かつ/または同じ型でない場合に true を返す。</td> + <td><code>var1 !== "3"<br> + 3 !== '3'</code></td> + </tr> + <tr> + <td>より大きい (>)</td> + <td>左のオペランドが右のオペランドよりも大きい場合に true を返す。</td> + <td><code>var2 > var1<br> + "12" > 2</code></td> + </tr> + <tr> + <td>以上 (>=)</td> + <td>左のオペランドが右のオペランド以上である場合に true を返す。</td> + <td><code>var2 >= var1<br> + var1 >= 3</code></td> + </tr> + <tr> + <td>より小さい (<)</td> + <td>左のオペランドが右のオペランドよりも小さい場合に true を返す。</td> + <td><code>var1 < var2<br> + "12" < "2"</code></td> + </tr> + <tr> + <td>以下 (<=)</td> + <td>左のオペランドが右のオペランド以下である場合に true を返す。</td> + <td><code>var1 <= var2<br> + var2 <= 5</code></td> + </tr> + </tbody> +</table> +<p><small><strong>表 3.3:比較演算子</strong></small></p> +<p>{{ PreviousNext("JavaScript/Guide/Operators/Assignment_Operators", "JavaScript/Guide/Operators/Arithmetic_Operators")}}</p> diff --git a/files/ja/web/javascript/guide/operators/logical_operators/index.html b/files/ja/web/javascript/guide/operators/logical_operators/index.html new file mode 100644 index 0000000000..fa6fa08068 --- /dev/null +++ b/files/ja/web/javascript/guide/operators/logical_operators/index.html @@ -0,0 +1,63 @@ +--- +title: 論理演算子 +slug: Web/JavaScript/Guide/Operators/Logical_Operators +--- +<h3 id=".E8.AB.96.E7.90.86.E6.BC.94.E7.AE.97.E5.AD.90" name=".E8.AB.96.E7.90.86.E6.BC.94.E7.AE.97.E5.AD.90">論理演算子</h3> +<p>論理演算子では基本的に真偽(論理)値を用います。そのような値があると真偽値を返します。しかし、&& および || 演算子は実際には指定されたオペランドの一方の値を返します。そのため、非真偽値とともに論理演算子が使われると非真偽値を返します。論理演算子について次の表で説明します。</p> +<table class="fullwidth-table"> + <tbody> + <tr> + <th>演算子</th> + <th>使用法</th> + <th>説明</th> + </tr> + <tr> + <td>&&</td> + <td>expr1 && expr2</td> + <td>(論理 AND)expr1 を false と見ることができる場合は expr1 を返す。そうでない場合は expr2 を返す。したがって、真偽値が使われた場合、両オペランドが true の場合は && は true を返し、そうでない場合は false を返す。</td> + </tr> + <tr> + <td>||</td> + <td>expr1 || expr2</td> + <td>(論理 OR)expr1 を true と見ることができる場合は expr1 を返す。そうでない場合は expr2 を返す。したがって、真偽値が使われた場合、どちらかのオペランドが true の場合は || は true を返し、両方とも false の場合は false を返す。</td> + </tr> + <tr> + <td>!</td> + <td>!expr</td> + <td>(論理 NOT)オペランドを true と見ることができる場合は false を返す。そうでない場合は true を返す。</td> + </tr> + </tbody> +</table> +<p><small><strong>表 3.7:論理演算子</strong></small></p> +<p>false と見ることができる式とは、null、0、空文字列 ("")、または undefined に評価される式のことです。</p> +<p>以下のコードで &&(論理 AND)演算子の例を示します。</p> +<pre>a1=true && true // t && t は true を返す +a2=true && false // t && f は false を返す +a3=false && true // f && t は false を返す +a4=false && (3 == 4) // f && f は false を返す +a5="Cat" && "Dog" // t && t は Dog を返す +a6=false && "Cat" // f && t は false を返す +a7="Cat" && false // t && f は false を返す +</pre> +<p>以下のコードで ||(論理 OR)演算子の例を示します。</p> +<pre>o1=true || true // t || t は true を返す +o2=false || true // f || t は true を返す +o3=true || false // t || f は true を返す +o4=false || (3 == 4) // f || f は false を返す +o5="Cat" || "Dog" // t || t は Cat を返す +o6=false || "Cat" // f || t は Cat を返す +o7="Cat" || false // t || f は Cat を返す +</pre> +<p>以下のコードで !(論理 NOT)演算子の例を示します。</p> +<pre>n1=!true // !t は false を返す +n2=!false // !f は true を返す +n3=!"Cat" // !t は false を返す +</pre> +<h4 id=".E3.82.B7.E3.83.A7.E3.83.BC.E3.83.88.E3.82.B5.E3.83.BC.E3.82.AD.E3.83.83.E3.83.88.E8.A9.95.E4.BE.A1" name=".E3.82.B7.E3.83.A7.E3.83.BC.E3.83.88.E3.82.B5.E3.83.BC.E3.82.AD.E3.83.83.E3.83.88.E8.A9.95.E4.BE.A1">ショートサーキット評価</h4> +<p>論理式は左から右に評価されるため、以下のルールを用いることで「ショートサーキット」評価ができるようになっています。</p> +<ul> + <li><code>false</code> && <em>anything</em> は false にショートサーキット評価する。</li> + <li><code>true</code> || <em>anything</em> は true ショートサーキット評価する。</li> +</ul> +<p>論理のルールはこれらの評価が常に正確であることを保証しています。上記の式の <em>anything</em> の部分は評価されないため、何らかの副作用が生じないように注意してください。</p> +<p>{{ PreviousNext("JavaScript/Guide/Operators/Bitwise_Operators", "JavaScript/Guide/Operators/String_Operators") }}</p> diff --git a/files/ja/web/javascript/guide/operators/special_operators/index.html b/files/ja/web/javascript/guide/operators/special_operators/index.html new file mode 100644 index 0000000000..226faf2b3c --- /dev/null +++ b/files/ja/web/javascript/guide/operators/special_operators/index.html @@ -0,0 +1,197 @@ +--- +title: 特殊演算子 +slug: Web/JavaScript/Guide/Operators/Special_Operators +--- +<h3 id=".E7.89.B9.E6.AE.8A.E6.BC.94.E7.AE.97.E5.AD.90" name=".E7.89.B9.E6.AE.8A.E6.BC.94.E7.AE.97.E5.AD.90">特殊演算子</h3> +<p>JavaScript は以下の特殊演算子があります。</p> +<ul> + <li>{{ Anch("条件演算子") }}</li> + <li>{{ Anch("コンマ演算子") }}</li> + <li>{{ Anch("delete") }}</li> + <li>{{ Anch("in") }}</li> + <li>{{ Anch("instanceof") }}</li> + <li>{{ Anch("new") }}</li> + <li>{{ Anch("this") }}</li> + <li>{{ Anch("typeof") }}</li> + <li>{{ Anch("void") }}</li> +</ul> +<h4 id=".E6.9D.A1.E4.BB.B6.E6.BC.94.E7.AE.97.E5.AD.90" name=".E6.9D.A1.E4.BB.B6.E6.BC.94.E7.AE.97.E5.AD.90">条件演算子</h4> +<p>条件演算子は JavaScript では唯一の 3 つのオペランドをとる演算子です。演算子は条件に基づいて 2 つの値のうち、1 つを選択します。構文は次のとおりです。</p> +<pre>condition ? val1 : val2 +</pre> +<p><code>condition</code> が true の場合、演算子は <code>val1</code> の値を選択します。そうでない場合は <code>val2</code> の値を選択します。標準的な演算子が使用できる場所でならどこででも条件演算子を使用することができます。</p> +<p>例えば、</p> +<pre>status = (age >= 18) ? "adult" : "minor" +</pre> +<p>この文では、<code>age</code> が 18 以上の場合 "adult" という値を変数 <code>status</code> に代入します。そうでない場合は "minor" という値を <code>status</code> に代入します。</p> +<h4 id=".E3.82.B3.E3.83.B3.E3.83.9E.E6.BC.94.E7.AE.97.E5.AD.90" name=".E3.82.B3.E3.83.B3.E3.83.9E.E6.BC.94.E7.AE.97.E5.AD.90">コンマ演算子</h4> +<p>コンマ演算子 (,) は単に両方のオペランドを評価し、第 2 のオペランドの値を返します。この演算子は主に <code>for</code> ループ内で使用されます。このことでループのたびに複数の変数を更新できるようになります。</p> +<p>例えば、a が一辺が 10 要素の 2 次元配列のとき、以下のコードではコンマ演算子を用いることで 2 変数を同時にインクリメントしています。このコードでは配列の対角成分の値を出力します。</p> +<pre>for (var i=0, j=9; i <= 9; i++, j--) + document.writeln("a["+i+"]["+j+"]= " + a[i][j]) +</pre> +<h4 id="delete" name="delete">delete</h4> +<p>delete 演算子はオブジェクトやオブジェクトのプロパティ、配列の指定されたインデックスの要素を削除します。構文は以下のとおりです。</p> +<pre>delete objectName +delete objectName.property +delete objectName[index] +delete property // with 文内でのみ有効 +</pre> +<p>ここで、<code>objectName</code> はオブジェクトの名前を、<code>property</code> は既存のプロパティを、<code>index</code> は配列の要素の位置を表す整数をそれぞれ表しています。</p> +<p>4 番目の形式は <code>with</code> 文内でのみ有効で、これはあるオブジェクトからプロパティを削除します。</p> +<p><code>delete</code> 演算子を使うことで暗黙的に宣言された変数を削除することができますが、<code>var</code> 文を用いて宣言された変数は削除できません。</p> +<p><code>delete</code> 演算子が成功すると、そのプロパティや要素には <code>undefined</code> がセットされます。また、演算が可能な場合は <code>delete</code> 演算子は true を返します。演算が不可能な場合は false を返します。</p> +<pre>x=42 +var y= 43 +myobj=new Number() +myobj.h=4 // プロパティ h を作成 +delete x // true を返す(暗黙的に宣言されているならば削除可能) +delete y // false を返す(var 付きで宣言されているなら削除不可能) +delete Math.PI // false を返す(定義済みプロパティは削除不可能) +delete myobj.h // true を返す(ユーザ定義プロパティは削除可能) +delete myobj // true を返す(暗黙的に宣言されているならば削除可能) +</pre> +<p><strong>配列要素の削除</strong><br> + 配列要素を削除したとき、配列の長さには影響を及ぼしません。例えば a{{ mediawiki.external(3) }} を削除したとき、a{{ mediawiki.external(4) }} は依然 a{{ mediawiki.external(4) }} のままで、a{{ mediawiki.external(3) }} は undefined になります。</p> +<p><code>delete</code> 演算子で配列要素を除去すると、もうその要素はその配列からなくなります。次の例では tree{{ mediawiki.external(3) }} は <code>delete</code> によって除去されます。</p> +<pre>trees=new Array("redwood","bay","cedar","oak","maple") +delete trees[3] +if (3 in trees) { + // ここは実行されない +} +</pre> +<p>配列要素は存在させたいが、値は未定義にしたいという場合は、<code>delete</code> 演算子の代わりに <code>undefined</code> キーワードを使用してください。次の例では <code>trees{{ mediawiki.external(3) }}</code> には <code>undefined</code> という値が代入されますが、その配列要素は存在したままになります。</p> +<pre>trees=new Array("redwood","bay","cedar","oak","maple") +trees[3]=undefined +if (3 in trees) { + // ここは実行される +} +</pre> +<h4 id="in" name="in">in</h4> +<p><code>in</code> 演算子は、指定されたプロパティが指定されたオブジェクトにある場合に true を返します。構文は以下のとおりです。</p> +<pre>propNameOrNumber in objectName +</pre> +<p>ここで、<code>propNameOrNumber</code> はプロパティ名か配列のインデックスを表す文字列式または数値式を、<code>objectName</code> はオブジェクトの名前をそれぞれ表しています。</p> +<p>次の例では <code>in</code> 演算子の使用法を示します。</p> +<pre>// 配列 +trees=new Array("redwood","bay","cedar","oak","maple") +0 in trees // true を返す +3 in trees // true を返す +6 in trees // false を返す +"bay" in trees // false を返す(インデックスの指す値ではなく、 + // インデックスの数字を指定しなければならない) +"length" in trees // true を返す(length は Array のプロパティ) + +// 定義済みオブジェクト +"PI" in Math // true を返す +myString=new String("coral") +"length" in myString // true を返す + +// ユーザ定義オブジェクト +mycar = {make:"Honda",model:"Accord",year:1998} +"make" in mycar // true を返す +"model" in mycar // true を返す +</pre> +<h4 id="instanceof" name="instanceof">instanceof</h4> +<p><code>instanceof</code> 演算子は、指定されたオブジェクトが指定されたオブジェクトの種類である場合に true を返します。構文は次のとおりです。</p> +<pre>objectName instanceof objectType +</pre> +<p>ここで、<code>objectName</code> は <code>objectType</code> と比較するオブジェクトの名前を、<code>objectType</code> は <code>Date</code> や <code>Array</code> のようなオブジェクトの種類をそれぞれ表しています。</p> +<p>実行時にオブジェクトの種類を確認する必要があるときは <code>instanceof</code> を使用してください。例えば、例外を受け取るとき、投げられた例外の種類によって別々の例外を扱うコードに分岐させることができます。</p> +<p>例えば、次のコードでは <code>instanceof</code> を使用することで <code>theDay</code> が <code>Date</code> オブジェクトであるかどうかを決定しています。<code>theDay</code> は <code>Date</code> オブジェクトなので <code>if</code> 文の中の文は実行されます。</p> +<pre>theDay=new Date(1995, 12, 17) +if (theDay instanceof Date) { + // 実行される文 +} +</pre> +<h4 id="new" name="new">new</h4> +<p><code>new</code> 演算子は、ユーザ定義オブジェクトや、<code>Array</code>、<code>Boolean</code>、<code>Date</code>、<code>Function</code>、<code>Image</code>、<code>Number</code>、<code>Object</code>、<code>Option</code>、<code>RegExp</code>、<code>String</code> といった定義済みオブジェクトのインスタンスを作成するのに使用します。サーバでは <code>DbPool</code>、<code>Lock</code>、<code>File</code>、<code>SendMail</code> といったオブジェクトも使用できます。<code>new</code> の使用法は以下のとおりです。</p> +<pre>objectName = new objectType ( param1 [,param2] ...[,paramN] ) +</pre> +<p>オブジェクト初期化子を使用してもオブジェクトを作成することができます。<a href="/ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers" title="ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers">オブジェクト初期化子の使用</a> にて説明しています。</p> +<p>詳しくはコア JavaScript リファレンスの <a href="/ja/Core_JavaScript_1.5_Reference/Operators/Special_Operators/new_Operator" title="ja/Core_JavaScript_1.5_Reference/Operators/Special_Operators/new_Operator">new 演算子</a> のページを参照してください。</p> +<h4 id="this" name="this">this</h4> +<p><code>this</code> キーワードを使うことでカレントオブジェクトを参照することができます。一般に <code>this</code> はあるメソッド内でそのメソッドを呼び出したオブジェクトを参照します。使用法は以下のとおりです。</p> +<pre>this[.propertyName] +</pre> +<p><strong>例 1</strong><br> + あるオブジェクトの <code>value</code> プロパティの妥当性を確認する <code>validate</code> という関数を想定します。関数にはそのオブジェクトと、上限および下限の値を渡します。</p> +<pre>function validate(obj, lowval, hival) { + if ((obj.value < lowval) || (obj.value > hival)) + alert("Invalid Value!") +} +</pre> +<p>各フォーム要素の <code>onChange</code> イベントハンドラにおいて <code>validate</code> を呼び出します。<code>this</code> を使うことでフォーム要素を渡すことができます。次の例をご覧ください。</p> +<pre><B>Enter a number between 18 and 99:</B> +<INPUT TYPE = "text" NAME = "age" SIZE = 3 + onChange="validate(this, 18, 99)"> +</pre> +<p><strong>例 2</strong><br> + <code>form</code> プロパティと組み合わせると <code>this</code> でカレントオブジェクトの親のフォームを参照できます。次の例では、<code>myForm</code> というフォームに <code>Text</code> オブジェクトとボタンが格納されています。ユーザがボタンをクリックすると、<code>Text</code> オブジェクトの値にフォーム名がセットされます。ボタンの <code>onClick</code> イベントハンドラは <code>this.form</code> を利用して親のフォームである <code>myForm</code> を参照します。</p> +<pre><FORM NAME="myForm"> +Form name:<INPUT TYPE="text" NAME="text1" VALUE="Beluga"> +<P> +<INPUT NAME="button1" TYPE="button" VALUE="Show Form Name" + onClick="this.form.text1.value=this.form.name"> +</FORM> +</pre> +<h4 id="typeof" name="typeof">typeof</h4> +<p><code>typeof</code> 演算子は次の方法のうち、どちらかの方法で使用します。</p> +<pre>1. typeof operand +2. typeof (operand) +</pre> +<p><code>typeof</code> 演算子は、未評価のオペランドの型を指す文字列を返します。<code>operand</code> は返される型を調べる対象となる文字列、変数、キーワード、オブジェクトです。括弧はあってもなくてもかまいません。</p> +<p>以下の変数を定義することを想定します。</p> +<pre>var myFun = new Function("5+2") +var shape="round" +var size=1 +var today=new Date() +</pre> +<p><code>typeof</code> 演算子はこれらの変数に対して以下の結果を返します。</p> +<pre>typeof myFun is function +typeof shape is string +typeof size is number +typeof today is object +typeof dontExist is undefined +</pre> +<p><code>true</code> や <code>null</code> というキーワードに対して、<code>typeof</code> 演算子は以下の結果を返します。</p> +<pre>typeof true is boolean +typeof null is object +</pre> +<p>数値や文字列に対して、<code>typeof</code> 演算子は以下の結果を返します。</p> +<pre>typeof 62 is number +typeof 'Hello world' is string +</pre> +<p>プロパティ値に対して、<code>typeof</code> 演算子はプロパティ値の型を返します。</p> +<pre>typeof document.lastModified is string +typeof window.length is number +typeof Math.LN2 is number +</pre> +<p>メソッドや関数に対して、<code>typeof</code> 演算子は以下の結果を返します。</p> +<pre>typeof blur is function +typeof eval is function +typeof parseInt is function +typeof shape.split is function +</pre> +<p>定義済みオブジェクトに対して、<code>typeof</code> 演算子は以下の結果を返します。</p> +<pre>typeof Date is function +typeof Function is function +typeof Math is function +typeof Option is function +typeof String is function +</pre> +<h4 id="void" name="void">void</h4> +<p><code>void</code> 演算子は次の方法のうち、どちらかの方法で使用します。</p> +<pre>1. void (expression) +2. void expression +</pre> +<p><code>void</code> 演算子は値を返さずに評価する式を指定します。<code>expression</code> は評価する JavaScript の式です。式の周りの括弧はあってもなくてもかまいませんが、使用したほうが見た目はいいです。</p> +<p><code>void</code> 演算子を使用することで式をハイパーテキストリンクとして指定することができます。式は評価されますが、開いている文書の代わりに読み込まれるということはありません。</p> +<p>以下のコードはユーザがクリックしても何も起こらないハイパーテキストリンクを作成します。ユーザがリンクをクリックすると <code>void(0)</code> は undefined に評価され、JavaScript としては影響を及ぼしません。</p> +<pre><A HREF="javascript:void(0)">Click here to do nothing</A> +</pre> +<p>以下のコードはユーザがクリックするとフォームが送信されるハイパーテキストリンクを作成します。</p> +<pre><A HREF="javascript:void(document.form.submit())"> +Click here to submit</A> +</pre> +<p>{{ PreviousNext("JavaScript/Guide/Operators/String_Operators", "JavaScript/Guide/Creating_a_Regular_Expression") }}</p> diff --git a/files/ja/web/javascript/guide/operators/string_operators/index.html b/files/ja/web/javascript/guide/operators/string_operators/index.html new file mode 100644 index 0000000000..41bf8bbc44 --- /dev/null +++ b/files/ja/web/javascript/guide/operators/string_operators/index.html @@ -0,0 +1,8 @@ +--- +title: 文字列演算子 +slug: Web/JavaScript/Guide/Operators/String_Operators +--- +<h2 id=".E6.96.87.E5.AD.97.E5.88.97.E6.BC.94.E7.AE.97.E5.AD.90" name=".E6.96.87.E5.AD.97.E5.88.97.E6.BC.94.E7.AE.97.E5.AD.90">文字列演算子</h2> +<p>比較演算子は文字列に使用できますが、これに加えて 2 つの文字列を結合する結合演算子 (+) も使用できます。これは 2 つのオペランドの文字列を結合した文字列を返します。例えば、<code>"my " + "string"</code> は <code>"my string"</code> という文字列を返します。</p> +<p>短縮表記した代入演算子 += も文字列の結合に使用できます。例えば、変数 <code>mystring</code> に "alpha" という値が格納されているとき、式 <code>mystring += "bet"</code> の評価結果は "alphabet" となり、この値を <code>mystring</code> に代入します。</p> +<p>{{ PreviousNext("JavaScript/Guide/Operators/Logical_Operators", "JavaScript/Guide/Operators/Special_Operators") }}</p> diff --git a/files/ja/web/javascript/guide/predefined_functions/escape_and_unescape_functions/index.html b/files/ja/web/javascript/guide/predefined_functions/escape_and_unescape_functions/index.html new file mode 100644 index 0000000000..aecb8a81f1 --- /dev/null +++ b/files/ja/web/javascript/guide/predefined_functions/escape_and_unescape_functions/index.html @@ -0,0 +1,14 @@ +--- +title: escape 関数と unescape 関数 +slug: Web/JavaScript/Guide/Predefined_Functions/escape_and_unescape_Functions +--- +<div class="onlyinclude"> + <h3 id="escape_.E3.81.8A.E3.82.88.E3.81.B3_unescape_.E9.96.A2.E6.95.B0" name="escape_.E3.81.8A.E3.82.88.E3.81.B3_unescape_.E9.96.A2.E6.95.B0">escape および unescape 関数</h3> + <p><code>escape</code> および <code>unescape</code> 関数は文字列をエンコードしたりデコードしたりします。<code>escape</code> 関数は ISO Latin 文字セットで表された引数の 16 進エンコーディングを返します。<code>unescape</code> は指定した 16 進エンコーディングの値に対する ASCII 文字列を返します。</p> + <p>これらの関数の構文は以下のとおりです。</p> + <pre>escape(string) +unescape(string) +</pre> + <p>これらの関数は主にサーバサイド JavaScript で URL 中の名前と値のペアのエンコードやデコードに使用されます。</p> + <code>escape</code> および <code>unescape</code> 関数は 非 ASCII 文字に対しては正しく機能せず、廃止予定になっています。JavaScript 1.5 以降では <code><a href="/ja/Core_JavaScript_1.5_Reference/Global_Functions/encodeURI" title="ja/Core_JavaScript_1.5_Reference/Global_Functions/encodeURI">encodeURI</a></code>、<code><a href="/ja/Core_JavaScript_1.5_Reference/Global_Functions/decodeURI" title="ja/Core_JavaScript_1.5_Reference/Global_Functions/decodeURI">decodeURI</a></code>、<code><a href="/ja/Core_JavaScript_1.5_Reference/Global_Functions/encodeURIComponent" title="ja/Core_JavaScript_1.5_Reference/Global_Functions/encodeURIComponent">encodeURIComponent</a></code> および <code><a href="/ja/Core_JavaScript_1.5_Reference/Global_Functions/decodeURIComponent" title="ja/Core_JavaScript_1.5_Reference/Global_Functions/decodeURIComponent">decodeURIComponent</a></code> を使用してください。</div> +<p>{{ PreviousNext("JavaScript/Guide/Predefined_Functions/Number_and_String_Functions", "JavaScript/Guide/Objects_and_Properties") }}</p> diff --git a/files/ja/web/javascript/guide/predefined_functions/eval_function/index.html b/files/ja/web/javascript/guide/predefined_functions/eval_function/index.html new file mode 100644 index 0000000000..3945955e86 --- /dev/null +++ b/files/ja/web/javascript/guide/predefined_functions/eval_function/index.html @@ -0,0 +1,12 @@ +--- +title: eval 関数 +slug: Web/JavaScript/Guide/Predefined_Functions/eval_Function +--- +<div class="onlyinclude"> + <h3 id="eval_.E9.96.A2.E6.95.B0" name="eval_.E9.96.A2.E6.95.B0">eval 関数</h3> + <p><code>eval</code> 関数は JavaScript のコードの文字列を特定のオブジェクトを参照することなく評価します。eval の構文は次のとおりです。</p> + <pre>eval(expr) +</pre> + <p>ここで <code>expr</code> は評価される文字列です。</p> + 文字列が式を表している場合は <code>eval</code> はその式を評価します。また、1 つ以上の JavaScript の文を表している場合は eval はその式を実行します。<code>eval</code> のコードのスコープは呼び出し元コードのスコープと同じです。演算式を評価するために <code>eval</code> を呼び出さないでください。JavaScript は自動的に演算式を評価します。</div> +<p>{{ PreviousNext("JavaScript/Guide/Predefined_Functions", "JavaScript/Guide/Predefined_Functions/isFinite_Function") }}</p> diff --git a/files/ja/web/javascript/guide/predefined_functions/index.html b/files/ja/web/javascript/guide/predefined_functions/index.html new file mode 100644 index 0000000000..758c6f22a0 --- /dev/null +++ b/files/ja/web/javascript/guide/predefined_functions/index.html @@ -0,0 +1,17 @@ +--- +title: 定義済み関数 +slug: Web/JavaScript/Guide/Predefined_Functions +--- +<div class="onlyinclude"> + <h3 id=".E5.AE.9A.E7.BE.A9.E6.B8.88.E3.81.BF.E9.96.A2.E6.95.B0" name=".E5.AE.9A.E7.BE.A9.E6.B8.88.E3.81.BF.E9.96.A2.E6.95.B0">定義済み関数</h3> + <p>JavaScript にはトップレベルの定義済み関数がいくつかあります。</p> + <ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Predefined_Functions/eval_Function" title="ja/Core_JavaScript_1.5_Guide/Predefined_Functions/eval_Function">eval</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Predefined_Functions/isFinite_Function" title="ja/Core_JavaScript_1.5_Guide/Predefined_Functions/isFinite_Function">isFinite</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Predefined_Functions/isNaN_Function" title="ja/Core_JavaScript_1.5_Guide/Predefined_Functions/isNaN_Function">isNaN</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Predefined_Functions/parseInt_and_parseFloat_Functions" title="ja/Core_JavaScript_1.5_Guide/Predefined_Functions/parseInt_and_parseFloat_Functions">parseInt と parseFloat</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Predefined_Functions/Number_and_String_Functions" title="ja/Core_JavaScript_1.5_Guide/Predefined_Functions/Number_and_String_Functions">Number と String</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/Predefined_Functions/escape_and_unescape_Functions" title="ja/Core_JavaScript_1.5_Guide/Predefined_Functions/escape_and_unescape_Functions">encodeURI と decodeURI、encodeURIComponent、decodeURIComponent(すべて Javascript 1.5 以降で使用可能)</a></li> + </ul> +</div> +<p>{{ PreviousNext("JavaScript/Guide/Using_the_arguments_object", "JavaScript/Guide/Predefined_Functions/eval_Function") }}</p> diff --git a/files/ja/web/javascript/guide/regular_expressions/assertions/index.html b/files/ja/web/javascript/guide/regular_expressions/assertions/index.html new file mode 100644 index 0000000000..e92e05b312 --- /dev/null +++ b/files/ja/web/javascript/guide/regular_expressions/assertions/index.html @@ -0,0 +1,246 @@ +--- +title: 言明 +slug: Web/JavaScript/Guide/Regular_Expressions/Assertions +tags: + - Assertions + - JavaScript + - Reference + - Regular Expressions + - regex +translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions +--- +<p>{{jsSidebar("JavaScript Guide")}}{{draft}}</p> + +<p>言明には、 行や単語の始まり・終わりを示す、境界や、(先読み、後読み、条件式を含む)何らかの方法でマッチが可能なことを示す、その他のパターンが含まれます。</p> + +<h2 id="Types" name="Types">種類</h2> + +<h3 id="境界型の言明">境界型の言明</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">文字</th> + <th scope="col">意味</th> + </tr> + <tr> + <td><code>^</code></td> + <td> + <p>入力の先頭にマッチします。複数行フラグが true にセットされている場合は、改行文字の直後にもマッチします。例えば <code>/^A/</code> は "an A" の 'A' にはマッチしませんが、"An E" の 'A' にはマッチします。</p> + + <div class="blockIndicator note"> + <p>この文字は、文字<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">集合</a>パターンの先頭にある場合は異なる意味を持ちます。</p> + </div> + </td> + </tr> + <tr> + <td><code>$</code></td> + <td> + <p>入力の末尾にマッチします。複数行フラグが true にセットされている場合は、改行文字の直前にもマッチします。例えば <code>/t$/</code> は "eater" の "t" にはマッチしませんが、"eat" の "t" にはマッチします。</p> + </td> + </tr> + <tr> + <td><code>\b</code></td> + <td> + <p>単語の区切りにマッチします。これは、単語構成文字と後に続く非単語構成文字の間、または非単語構成文字と後に続く単語構成文字の間、または文字列の先頭・最後です。単語の区切りはマッチする「文字」ではありません。アンカーのように、単語の区切りはマッチした部分に含まれません。言い換えると、マッチした単語の区切りの長さは 0 です。</p> + + <p>入力文字に "moon" を使用した例:</p> + + <ul> + <li><code>/\bm/</code> は "m" にマッチします。これは `\b` が文字列の先頭に存在するからです。</li> + <li><code>/oo\b/</code> は "oo" にマッチしません。これは '\b' の前後に単語構成文字があるためです。</li> + <li><code>/oon\b/</code> は "oon" にマッチします。これは、文字列の終端であるためです。</li> + <li><code>/\w\b\w/</code> はどこにもマッチしないでしょう。これは、'\b' の前後に単語構成文字があるためです。</li> + </ul> + + <p>バックスペース文字 ([\b]) については<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">文字クラス</a>を見てください。</p> + </td> + </tr> + <tr> + <td><code>\B</code></td> + <td> + <p>単語の区切り以外にマッチします。マッチするのは以下の場合です:</p> + + <ul> + <li>文字列の先頭の文字の前</li> + <li>文字列の終端の文字の後</li> + <li>単語内の 2 文字の間</li> + <li>2 つの単語ではない文字の間</li> + <li>空文字列</li> + </ul> + + <p>例えば <code>/\B../</code> は "noonday" の 'oo' に、<code>/y\B./</code> は "possibly yesterday" の 'ye' にマッチします。</p> + </td> + </tr> + </thead> +</table> + +<h3 id="その他の言明">その他の言明</h3> + +<div class="blockIndicator note"> +<p><code>?</code> 文字は数量詞として使うことができます。</p> +</div> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">文字</th> + <th scope="col">意味</th> + </tr> + </thead> + <tbody> + <tr> + <td>x(?=y)</td> + <td> + <p><strong>先読み言明:</strong> <em><code>x</code></em> に <em><code>y</code></em> が続く場合のみ <em><code>x</code></em> にマッチします。例えば <code>/Jack(?=Sprat)/</code> は "Jack" の後に "Sprat" が続く場合のみ "Jack" にマッチします。<br> + <code>/Jack(?=Sprat|Frost)/</code> は "Jack" の後ろに "Sprat" または "Frost" が続く場合のみ "Jack" にマッチします。しかしながら、"Sprat" も "Frost" もマッチの結果には表れません。</p> + </td> + </tr> + <tr> + <td>x(?!y)</td> + <td> + <p><strong>否定先読み言明:</strong> <em><code>x</code></em> に <code><em>y</em></code> が続かない場合のみ <em><code>x</code></em> にマッチします。例えば <code>/\d+(?!\.)/</code> は後ろに小数点が続かない数値にマッチします。正規表現 <code>/\d+(?!\.)/.exec("3.141")</code> は "141" にマッチしますが "3.141" にはマッチしません。</p> + </td> + </tr> + <tr> + <td>(?<=y)x</td> + <td> + <p><strong>後読み言明:</strong> <code><em>y</em></code> に <em><code>x</code></em> が続く場合のみ <code><em>x</em></code> にマッチします。例えば、<code>/(?<=Jack)Sprat/</code> は "Jack" に続く "Sprat" のみにマッチします。 <code>/(?<=Jack|Tom)Sprat/</code> は "Jack" または "Tom" に続く "Sprat" のみにマッチします。しかしながら、"Jack" も "Tom" もマッチの結果には表れません。</p> + </td> + </tr> + <tr> + <td>(?<!y)x</td> + <td> + <p><strong>否定後読み言明:</strong> <em><code>y</code></em> に <code><em>x</em></code> が続かない場合のみ <em><code>x</code></em> にマッチします。例えば、<code>/(?<!-)\d+/</code> は、マイナス記号のつかない数字のみにマッチします。 <code>/(?<!-)\d+/.exec('3')</code> は "3" がマッチします。 <code>/(?<!-)\d+/.exec('-3')</code> はマイナス記号に数字が続いているため、マッチが見つかりません。</p> + </td> + </tr> + </tbody> +</table> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="基本的な境界型の例">基本的な境界型の例</h3> + +<pre class="brush: js">// おかしい文字列を修正するために正規表現の境界を利用します。 +buggyMultiline = `tey, ihe light-greon apple +tangs on ihe greon traa`; + +// 1) 文字列の最初と改行の直後のマッチを修正するために ^ を利用します。 +buggyMultiline = buggyMultiline.replace(/^t/gim,'h'); +console.log(1, buggyMultiline); // 'tey', 'tangs' を 'hey', 'hangs' に修正します。 'traa' は対象外です。 + +// 2) テキストの末尾を修正するために $ を利用します。 +buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.'); +console.log(2, buggyMultiline); // 'traa' を 'tree' に修正します。 + +// 3) 単語と空白の間の境界の右の文字にマッチさせるために \b を利用します。 +buggyMultiline = buggyMultiline.replace(/\bi/gim,'t'); +console.log(3, buggyMultiline); // 'ihe' を修正しますが、'light'は対象外です。 + +// 4) エンティティの境界内の文字にマッチするために \B を利用します。 +fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e'); +console.log(4, fixedMultiline); // 'greon' を修正しますが、'on' は対象外です。</pre> + +<h3 id="制御文字を利用した入力の開始へのマッチ">^ 制御文字を利用した入力の開始へのマッチ</h3> + +<p> <code>^</code> は、通常、単語の開始にマッチさせるために利用します。この例では、<code>/^A/ </code>という正規表現で 'A' で始まるフルーツを取得します。ここでの <code>^</code> は、入力の開始を示すという、たった 1 つの役割を果たしています。適切なフルーツを選択するために<a href="/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions">アロー</a> 関数で <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">filter </a>メソッドを用います。</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> fruits <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">"Apple"</span><span class="punctuation token">,</span> <span class="string token">"Watermelon"</span><span class="punctuation token">,</span> <span class="string token">"Orange"</span><span class="punctuation token">,</span> <span class="string token">"Avocado"</span><span class="punctuation token">,</span> <span class="string token">"Strawberry"</span><span class="punctuation token">]</span><span class="punctuation token">;</span> + +<span class="comment token">// /^A/ 正規表現で 'A' で始まるフルーツを選択します。</span> +<span class="comment token">// ここでの'^' 制御記号は「入力の開始にマッチする」という 1 つの役割だけで利用されています。</span> + +<span class="keyword token">let</span> fruitsStartsWithA <span class="operator token">=</span> fruits<span class="punctuation token">.</span><span class="function token">filter</span><span class="punctuation token">(</span><span class="parameter token">fruit</span> <span class="operator token">=></span> <span class="regex token">/^A/</span><span class="punctuation token">.</span><span class="function token">test</span><span class="punctuation token">(</span>fruit<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>fruitsStartsWithA<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'Apple', 'Avocado' ]</span></code></pre> + +<p>2 番目の例での <code>^</code> は、入力の開始へのマッチと、<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">グル―プ</a>で用いられた場合の文字集合の否定または補集合という、両方で利用されています。</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> fruits <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">"Apple"</span><span class="punctuation token">,</span> <span class="string token">"Watermelon"</span><span class="punctuation token">,</span> <span class="string token">"Orange"</span><span class="punctuation token">,</span> <span class="string token">"Avocado"</span><span class="punctuation token">,</span> <span class="string token">"Strawberry"</span><span class="punctuation token">]</span><span class="punctuation token">;</span> + +<span class="comment token">// /^[^A]/ という正規表現で 'A' で始まらないフルーツを選択します。</span> +<span class="comment token">// この例では、'^' 制御記号は 2 つの意味を表しています。</span> +<span class="comment token">// 1) 入力の開始にマッチ +// 2) [^A]という文字集合の否定または補集合: </span> +<span class="comment token">// つまり、角括弧で囲まれたものでないあらゆるものにマッチします</span> + +<span class="keyword token">let</span> fruitsStartsWithNotA <span class="operator token">=</span> fruits<span class="punctuation token">.</span><span class="function token">filter</span><span class="punctuation token">(</span><span class="parameter token">fruit</span> <span class="operator token">=></span> <span class="regex token">/^[^A]/</span><span class="punctuation token">.</span><span class="function token">test</span><span class="punctuation token">(</span>fruit<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>fruitsStartsWithNotA<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'Watermelon', 'Orange', 'Strawberry' ]</span></code></pre> + +<h3 id="単語の境界にマッチ">単語の境界にマッチ</h3> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> fruitsWithDescription <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">"Red apple"</span><span class="punctuation token">,</span> <span class="string token">"Orange orange"</span><span class="punctuation token">,</span> <span class="string token">"Green Avocado"</span><span class="punctuation token">]</span><span class="punctuation token">;</span> + +<span class="comment token">// 単語の終わりに 'en' または 'ed' を含む記述を選択します。</span> +<span class="keyword token">let</span> enEdSelection <span class="operator token">=</span> fruitsWithDescription<span class="punctuation token">.</span><span class="function token">filter</span><span class="punctuation token">(</span><span class="parameter token">descr</span> <span class="operator token">=></span> <span class="regex token">/(en|ed)\b/</span><span class="punctuation token">.</span><span class="function token">test</span><span class="punctuation token">(</span>descr<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>enEdSelection<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'Red apple', 'Green Avocado' ]</span></code></pre> + +<h3 id="先読み言明">先読み言明</h3> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="comment token">// JS Lookahead assertion x(?=y)</span> + +<span class="keyword token">let</span> regex <span class="operator token">=</span> <span class="regex token">/First(?= test)/g</span><span class="punctuation token">;</span> + +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'First test'</span><span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'First' ]</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'First peach'</span><span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// null</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'This is a First test in a year.'</span><span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'First' ]</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'This is a First peach in a month.'</span><span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// null</span></code></pre> + +<h3 id="基本的な否定先読み言明">基本的な否定先読み言明</h3> + +<p>例えば、<code style="font-size: 1rem; letter-spacing: -0.00278rem;">/\d+(?!\.)/</code><span style="font-size: 1rem; letter-spacing: -0.00278rem;"> は小数点が後に続かない数値にだけマッチします。</span><code>/\d+(?!\.)/.exec('3.141')</code> は "141" にマッチしますが、 "3" にはマッチしません。</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js">console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="regex token">/\d+(?!\.)/g</span><span class="punctuation token">.</span><span class="function token">exec</span><span class="punctuation token">(</span><span class="string token">'3.141'</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ '141', index: 2, input: '3.141' ]</span></code></pre> + +<h3 id="言明と範囲における_!_の組み合わせの異なる意味での利用">言明と範囲における '?!' の組み合わせの異なる意味での利用</h3> + +<p> <code>?!</code> の組み合わせを利用するとき、<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">言明</a> <code>/x(?!y)/ </code>と<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">範囲</a> <code>[^?!]</code>では異なる意味を持ちます。</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> orangeNotLemon <span class="operator token">=</span> <span class="string token">"Do you want to have an orange? Yes, I do not want to have a lemon!"</span><span class="punctuation token">;</span> + +<span class="comment token">// 言明 /x(?!y)/ と範囲 /[^?!]/ では '?!' の組み合わせの利用は異なる意味を持ちます。</span> +<span class="keyword token">let</span> selectNotLemonRegex <span class="operator token">=</span> <span class="regex token">/[^?!]+have(?! a lemon)[^?!]+[?!]/gi</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>orangeNotLemon<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>selectNotLemonRegex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'Do you want to have an orange?' ]</span> + +<span class="keyword token">let</span> selectNotOrangeRegex <span class="operator token">=</span> <span class="regex token">/[^?!]+have(?! an orange)[^?!]+[?!]/gi</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>orangeNotLemon<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>selectNotOrangeRegex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ ' Yes, I do not want to have a lemon!' ]</span></code></pre> + +<h3 id="後読み言明">後読み言明</h3> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> oranges <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">'ripe orange A '</span><span class="punctuation token">,</span> <span class="string token">'green orange B'</span><span class="punctuation token">,</span> <span class="string token">'ripe orange C'</span><span class="punctuation token">,</span><span class="punctuation token">]</span><span class="punctuation token">;</span> + +<span class="keyword token">let</span> ripe_oranges <span class="operator token">=</span> oranges<span class="punctuation token">.</span><span class="function token">filter</span><span class="punctuation token">(</span> <span class="parameter token">fruit</span> <span class="operator token">=></span> fruit<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span><span class="regex token">/(?<=ripe )orange/</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>ripe_oranges<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'ripe orange A ', 'ripe orange C' ]</span></code></pre> + +<h2 id="仕様">仕様</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様</th> + <th scope="col">策定状況</th> + <th scope="col">コメント</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assertion', 'RegExp: Assertions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="ブラウザサポート">ブラウザサポート</h2> + +<div> + + +<p>{{Compat("javascript.builtins.RegExp.assertions")}}</p> +</div> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions">正規表現</a></li> + <li><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp"><code>RegExp()</code> コンストラクタ</a></li> +</ul> diff --git a/files/ja/web/javascript/guide/regular_expressions/character_classes/index.html b/files/ja/web/javascript/guide/regular_expressions/character_classes/index.html new file mode 100644 index 0000000000..accc601eef --- /dev/null +++ b/files/ja/web/javascript/guide/regular_expressions/character_classes/index.html @@ -0,0 +1,216 @@ +--- +title: 文字クラス +slug: Web/JavaScript/Guide/Regular_Expressions/Character_Classes +tags: + - JavaScript + - Reference + - RegExp + - Regular Expressions +translation_of: Web/JavaScript/Guide/Regular_Expressions/Character_Classes +--- +<p>{{JSSidebar("JavaScript Guide")}}{{Draft}}</p> + +<p>文字クラスは、文字や数字の区別など、文字の種類を区別します。</p> + +<h2 id="Types" name="Types">種類</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">文字</th> + <th scope="col">意味</th> + </tr> + </thead> + <tbody> + </tbody> + <tbody> + <tr> + <td><code>.</code></td> + <td> + <p>次のいずれかの意味を持ちます。</p> + + <ul> + <li>行末文字 ( <code>\n</code>、<code>\r</code>、<code>\u2028</code>、<code>\u2029</code> ) を除くあらゆる 1 文字とマッチします。例えば、<code>/.y/</code> は "my" と "ay" にマッチし、"yes make my day" の "yes" にはマッチしません。</li> + <li>文字セット内では <code>.</code> はその特別な意味を失い、文字通りの "."と一致します。</li> + </ul> + + <p>複数行フラグ (<code>m</code>) は "." の意味を変えないことに注意してください。そのため、複数行にわたるパターンに一致させるには、(IEの古いバージョン以外なら)文字集合 <code>[^]</code> を使うことで、改行を含む任意の文字に一致します。</p> + + <p><strong>ES2018</strong> では <code>s</code> "dotAll" フラグが追加されました。これは行末文字と一致することを可能にします。</p> + </td> + </tr> + <tr> + <td><code>\d</code></td> + <td> + <p>あらゆる(アラビア)数字にマッチします。<code>[0-9]</code> に相当します。例えば <code>/\d/</code> や <code>/[0-9]/</code> は "B2 is the suite number" の "2" にマッチします。</p> + </td> + </tr> + <tr> + <td><code>\D</code></td> + <td> + <p>あらゆる(アラビア)数字以外の文字にマッチします。<code>[^0-9]</code> に相当します。例えば <code>/\D/</code> や <code>/[^0-9]/</code> は "B2 is the suite number" の "B" にマッチします。</p> + </td> + </tr> + <tr> + <td><code>\w</code></td> + <td> + <p>アンダースコアを含むあらゆる半角英数字(基本ラテンアルファベット)にマッチします。<code>[A-Za-z0-9_]</code> に相当します。例えば <code>/\w/</code> は、"apple," の 'a' や "$5.28," の "5" や "3D" の "3" にマッチします。</p> + </td> + </tr> + <tr> + <td><code>\W</code></td> + <td> + <p>前述以外の文字にマッチします。<code>[^A-Za-z0-9_]</code> に相当します。例えば <code>/\W/</code> や <code>/[^A-Za-z0-9_]/</code> は、"50%" の "%" にマッチします。</p> + </td> + </tr> + <tr> + <td><code>\s</code></td> + <td> + <p>スペース、タブ、改ページ、改行を含むホワイトスペース文字にマッチします。<code>[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]</code> に相当します。例えば <code>/\s\w*/</code> は <code>"foo bar"</code> の <code>" bar"</code> にマッチします。</p> + </td> + </tr> + <tr> + <td><code>\S</code></td> + <td> + <p>ホワイトスペース以外の文字にマッチします。<code>[^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]</code> に相当します。例えば <code>/\S\w*/</code> は "foo bar" の "foo" にマッチします。</p> + </td> + </tr> + <tr> + <td><code>\t</code></td> + <td>タブ (U+0009) にマッチします。</td> + </tr> + <tr> + <td><code>\r</code></td> + <td>復帰文字 (U+000D) にマッチします。</td> + </tr> + <tr> + <td><code>\n</code></td> + <td>改行文字 (U+000A) にマッチします。</td> + </tr> + <tr> + <td><code>\v</code></td> + <td>垂直タブ (U+000B) にマッチします。</td> + </tr> + <tr> + <td><code>\f</code></td> + <td>改ページ (U+000C) にマッチします。</td> + </tr> + <tr> + <td><code>[\b]</code></td> + <td>後退文字(バックスペース、U+0008)にマッチします。単語境界文字 (<code>\b</code>) については<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Boundaries">境界</a>を見てください。</td> + </tr> + <tr> + <td><code>\0</code></td> + <td>NULL 文字 (U+0000) にマッチします。この後ろに他の数字を続けてはいけません。<code>\0</code> の後に(0 から 7 までの)数字が続くと 8 進数の<a href="/ja/docs/Web/JavaScript/Reference/Lexical_grammar#Octal">エスケープシーケンス</a>となるからです。</td> + </tr> + <tr> + <td><code>\c<em>X</em></code></td> + <td> + <p><code><em>X</em></code> には A から Z のうち 1 文字が入ります。文字列中の制御文字にマッチします。例えば <code>/\cM/</code> は文字列中の control-M (U+000D) にマッチします。</p> + </td> + </tr> + <tr> + <td><code>\x<em>hh</em></code></td> + <td><code>hh</code>(2 桁の 16 進数)コードからなる文字にマッチします。</td> + </tr> + <tr> + <td><code>\u<em>hhhh</em></code></td> + <td><code>hhhh</code>(4 桁の 16 進数)の値からなる UTF-16 コードユニットにマッチします。</td> + </tr> + <tr> + <td><code>\u<em>{hhhh}</em></code> または <code><em>\u{hhhhh}</em></code></td> + <td> + <p>(<code>u</code> フラグがセットされた時のみ)<strong> </strong> <code>U+<em>hhhh</em></code> または <code>U+<em>hhhhh</em></code> (16 進数) Unicode 値からなる文字にマッチします。</p> + </td> + </tr> + <tr> + <td><code>\</code></td> + <td> + <p>次の文字を特別に扱うこと、「エスケープ」することを示します。 その振る舞いは、2 通りのうちのどちらか 1 つです。</p> + + <ul> + <li>通常文字の前に付けられた場合、次の文字が特別なもので、文字通りには評価されないことを示します。例えば <code>b</code> は文字 <code>"b"</code> にマッチします。しかし "b" の前にバックスラッシュを置いて <code>\b</code> とすると、<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Boundaries">単語区切り</a>を意味するようになります。</li> + <li>特殊文字の前に付けられた場合、次の文字が特別なものでなく、文字通りに評価されることを表します。例えば、<code>"*"</code> は、先行文字の 0 回以上の出現が一致する必要があることを意味する特殊文字です。例えば、<code>/a*/</code> は 0 回以上の <code>"a"</code> とマッチします。文字通りの <code>*</code> にマッチさせるには、その直前にバックスラッシュを入れます。例えば、<code>/a\*/</code> は <code>"a*"</code> とマッチします。</li> + </ul> + + <div class="blockIndicator note"> + <p>この文字を文字通りにマッチさせるには、それ自身をエスケープします。つまり、 <code>/\\/</code> を使って <code>\</code> を検索します。</p> + </div> + </td> + </tr> + </tbody> +</table> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="一連の数字を探す">一連の数字を探す</h3> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> randomData <span class="operator token">=</span> <span class="string token">"015 354 8787 687351 3512 8735"</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> regexpFourDigits <span class="operator token">=</span> <span class="regex token">/\b\d{4}\b/g</span><span class="punctuation token">;</span> +<span class="comment token">// \b は境界を示します(つまり、単語の真ん中からマッチを開始しません)</span> +<span class="comment token">// \d{4} は 4 つの数字を示します</span> +<span class="comment token">// \b は別の境界を示します(つまり、単語の真ん中でマッチが終わりません)</span> + + +console<span class="punctuation token">.</span><span class="function token">table</span><span class="punctuation token">(</span>randomData<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regexpFourDigits<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="comment token">// ['8787', '3512', '8735']</span></code></pre> + +<h3 id="A_から始まる(ラテンアルファベットの)単語を探す">A から始まる(ラテンアルファベットの)単語を探す</h3> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> aliceExcerpt <span class="operator token">=</span> <span class="string token">"I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all."</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> regexpWordStartingWithA <span class="operator token">=</span> <span class="regex token">/\b[aA]\w+/g</span><span class="punctuation token">;</span> +<span class="comment token">// \b は境界を示します(つまり、単語の真ん中からマッチを開始しません)</span> +<span class="comment token">// [aA] は a または A の文字を示します</span> +<span class="comment token">// \w+ は複数回の *ラテンアルファベットからなる* 任意の文字を示します</span> + +console<span class="punctuation token">.</span><span class="function token">table</span><span class="punctuation token">(</span>aliceExcerpt<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regexpWordStartingWithA<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="comment token">// ['Ada', 'and', 'at', 'all']</span></code></pre> + +<h3 id="(ユニコード文字の)単語を探す">(ユニコード文字の)単語を探す</h3> + +<p>単語を表すために、ラテンアルファベットではなく、 <span class="ILfuVd"><span class="e24Kjd">Unicode</span></span> 文字の範囲が使えます。(つまり、ロシア語やアラビア語のような他の言語のテキストを扱えます。) <span class="ILfuVd"><span class="e24Kjd">Unicode</span></span> の 「<span class="ILfuVd"><span class="e24Kjd">基本多言語面</span></span>」には、世界中で使われているほとんどの文字が含まれており、それらの文字で書かれた単語にマッチするための文字クラスと範囲を利用できます。</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> nonEnglishText <span class="operator token">=</span> <span class="string token">"Приключения Алисы в Стране чудес"</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> regexpBMPWord <span class="operator token">=</span> <span class="regex token">/([\u0000-\u0019\u0021-\uFFFF])+/gu</span><span class="punctuation token">;</span> +<span class="comment token">// U+0000 から U+FFFF までの BMP、ただし、U+0020</span> は空白 + +console<span class="punctuation token">.</span><span class="function token">table</span><span class="punctuation token">(</span>nonEnglishText<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regexpBMPWord<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">[</span> <span class="string token">'Приключения'</span><span class="punctuation token">,</span> <span class="string token">'Алисы'</span><span class="punctuation token">,</span> <span class="string token">'в'</span><span class="punctuation token">,</span> <span class="string token">'Стране'</span><span class="punctuation token">,</span> <span class="string token">'чудес'</span> <span class="punctuation token">]</span></code></pre> + +<div class="hidden"> +<p>Note for MDN editors: please do not try to add funny examples with emoji as those characters are not handled by the platform (Kuma).</p> +</div> + +<h2 id="Specifications" name="Specifications">仕様</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">仕様書</th> + <th scope="col">策定状況</th> + <th scope="col">コメント</th> + </tr> + </thead> + <tbody> + <tr> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-characterclass', 'RegExp: Character classes')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_support" name="Browser_support">ブラウザサポート</h2> + + + +<p>{{Compat("javascript.builtins.RegExp.character_classes")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions">正規表現</a></li> + <li><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp"><code>RegExp()</code> コンストラクタ</a></li> +</ul> diff --git a/files/ja/web/javascript/guide/regular_expressions/groups_and_ranges/index.html b/files/ja/web/javascript/guide/regular_expressions/groups_and_ranges/index.html new file mode 100644 index 0000000000..d79009b14e --- /dev/null +++ b/files/ja/web/javascript/guide/regular_expressions/groups_and_ranges/index.html @@ -0,0 +1,162 @@ +--- +title: グループと範囲 +slug: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges +tags: + - Guide + - JavaScript + - Reference + - Regular Expressions + - regex +translation_of: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges +--- +<p>{{jsSidebar("JavaScript Guide")}}{{draft}}</p> + +<p>グループと範囲は、式にある文字のグループと範囲を示します。</p> + +<h2 id="Types" name="Types">種類</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">文字</th> + <th scope="col">意味</th> + </tr> + </thead> + <tbody> + <tr> + <td><code><em>x</em>|<em>y</em></code></td> + <td> + <p>"x" または "y" にマッチします。例えば <code>/green|red/</code> は "green apple" の "green" や "red apple" の "red" にマッチします。</p> + </td> + </tr> + <tr> + <td><code>[xyz]<br> + [a-c]</code></td> + <td> + <p>文字集合です。角括弧で囲まれた文字のいずれか 1 個にマッチします。ハイフンを用いて文字の範囲を指定することも可能ですが、ハイフンが括弧に囲まれた最初または最後の文字に現れている場合、それはハイフンリテラルとみなされて、通常文字として文字集合に含まれます。文字集合には文字クラスを含めることができます。</p> + + <p>例えば <code>[abcd]</code> は <code>[a-d]</code> と同じです。これは "brisket" の "b" や "chop" の "c" にマッチします。</p> + + <p>例えば、<code>[abcd-]</code> と <code>[-abcd]</code> は "brisket" の "b" と "chop" の "c" と "non-profit" の "-" (ハイフン)とマッチします。</p> + + <p>例えば、<code>[\w-]</code> は <code>[A-Za-z0-9_-]</code> と同じです。これは "brisket" の "b" や "chop" の "c" 、"non-profit" の "n" にマッチします。</p> + </td> + </tr> + <tr> + <td> + <p><code>[^xyz]<br> + [^a-c]</code></p> + </td> + <td> + <p>文字集合の否定または補集合です。角括弧で囲まれた文字ではない文字にマッチします。ハイフンを用いて文字の範囲を指定することも可能ですが、ハイフンが括弧に囲まれた最初または最後の文字に現れている場合、それはハイフンリテラルとみなされて、通常文字として文字集合に含まれます。例えば <code>[^abc]</code> は <code>[^a-c]</code> と同じです。これは "bacon" の 'o' や "chop" の 'h' にマッチします。</p> + + <div class="blockIndicator note"> + <p>^ 文字は<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Boundaries">入力の先頭</a>を示すこともできます。</p> + </div> + </td> + </tr> + <tr> + <td><code>(<em>x</em>)</code></td> + <td> + <p><strong>キャプチャグループ:</strong> <code><em>x</em></code> にマッチし、マッチした内容を記憶します。例えば <code>/(foo)/</code> は "foo bar" の "foo" にマッチし、記憶します。</p> + + <p>正規表現は複数のキャプチャグループを持つことができます。結果、一般的にキャプチャグループ内の左括弧と同じ順にある、配列の要素のキャプチャグループに一致しています。たいていの場合、これはキャプチャグループ自身の順番です。これはキャプチャグループがネストしている場合に重要です。マッチは結果の要素のインデックス (<code>[1], ..., [n]</code>) や、あらかじめ定義されている <code>RegExp</code> オブジェクトのプロパティ (<code>$1, ..., $9</code>) を使ってアクセスできます。</p> + + <p>キャプチャグループはパフォーマンスペナルティがあります。マッチした部分文字列を使わない場合はキャプチャしない括弧(後述)を使ったほうがいいでしょう。</p> + + <p>全体マッチ (<code>/.../g</code>) がある場合、{{JSxRef("String.match()")}} はグループを返せません。ですが、 {{JSxRef("String.matchAll()")}} によってすべてのマッチを取得できます。</p> + </td> + </tr> + <tr> + <td><code>\<em>n</em></code></td> + <td> + <p><code><em>n</em></code> に正の整数が入ります。正規表現内において n 番目の括弧の部分にマッチした最新の部分文字列への後方参照となります(括弧の数は左からカウントします)。例えば <code>/apple(,)\sorange\1/</code> は "apple, orange, cherry, peach" の "apple, orange," にマッチします。A complete example follows this table.</p> + </td> + </tr> + <tr> + <td><code>(?<Name>x)</code></td> + <td> + <p><strong>名前付きキャプチャグループ:</strong> <code>x</code> にマッチし、<code><Name></code> で指定された名前に従い、返されるマッチの <code>groups</code> プロパティに記憶されます。三角括弧 ('<code><</code>' と '<code>></code>') にはグループ名が必須です。</p> + + <p>例えば、電話番号からアメリカのエリアコードを取り出す際、<code>/\((?<area>\d\d\d)\)/</code> を使うことができます。 結果の番号は <code>matches.groups.area</code> に表示されます。</p> + </td> + </tr> + <tr> + <td><code>(?:<em>x</em>)</code></td> + <td> + <p><strong>非キャプチャグループ:</strong> <em><code>x</code></em> にマッチしますが、マッチした内容は記憶しません。マッチの部分文字列は、結果の配列の要素 (<code>[1], ..., [n]</code>) や、あらかじめ定義されている <code>RegExp</code> オブジェクトのプロパティ (<code>$1, ..., $9</code>) から呼び出すことはできません。.</p> + </td> + </tr> + </tbody> +</table> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="母音を数える">母音を数える</h3> + +<pre class="brush: js">var aliceExcerpt = "There was a long silence after this, and Alice could only hear whispers now and then."; +var regexpVowels = /[aeiouy]/g; + +console.log("母音の数:", aliceExcerpt.match(regexpVowels).length); +// 母音の数: 25</pre> + +<h3 id="グループの使い方">グループの使い方</h3> + +<pre class="brush: js">let personList = `First_Name: John, Last_Name: Doe +First_Name: Jane, Last_Name: Smith`; + +let regexpNames = /First_Name: (\w+), Last_Name: (\w+)/mg; +let match = regexpNames.exec(personList); +do { + console.log(`Hello ${match[1]} ${match[2]}`); +} while((match = regexpNames.exec(personList)) !== null); +</pre> + +<h3 id="名前付きグループの使い方">名前付きグループの使い方</h3> + +<pre class="brush: js">let personList = `First_Name: John, Last_Name: Doe +First_Name: Jane, Last_Name: Smith`; + +let regexpNames = /First_Name: (?<firstname>\w+), Last_Name: (?<lastname>\w+)/mg; +let match = regexpNames.exec(personList); +do { + console.log(`Hello ${match.groups.firstname} ${match.groups.lastname}`); +} while((match = regexpNames.exec(personList)) !== null);</pre> + +<div class="blockIndicator note"> +<p><strong>注:</strong> すべてのブラウザがこの機能をサポートしているわけではありません。以下の互換性の表を参照してください。</p> +</div> + +<h2 id="仕様">仕様</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様</th> + <th scope="col">策定状況</th> + <th scope="col">コメント</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-classranges', 'RegExp: Ranges')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_support" name="Browser_support">ブラウザサポート</h2> + +<div> + + +<div class="hidden">Firefox currently doesn't support named groups. See <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1362154">corresponding issue</a>. — make sure to include this inside groups_ranges</div> + +<p>{{Compat("javascript.builtins.RegExp.groups_ranges")}}</p> +</div> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions">正規表現</a></li> + <li><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp"><code>RegExp()</code> コンストラクタ</a></li> +</ul> diff --git a/files/ja/web/javascript/guide/regular_expressions/index.html b/files/ja/web/javascript/guide/regular_expressions/index.html new file mode 100644 index 0000000000..a6a571bb88 --- /dev/null +++ b/files/ja/web/javascript/guide/regular_expressions/index.html @@ -0,0 +1,800 @@ +--- +title: 正規表現 +slug: Web/JavaScript/Guide/Regular_Expressions +tags: + - Guide + - Intermediate + - JavaScript + - Reference + - RegExp + - Regular Expressions + - regex +translation_of: Web/JavaScript/Guide/Regular_Expressions +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}</div> + +<p class="summary">正規表現とは、文字列内で文字の組み合わせを照合するために用いられるパターンです。JavaScript では、正規表現はオブジェクトでもあります。これらのパターンは {{jsxref("RegExp")}} の {{jsxref("RegExp.exec", "exec")}} および {{jsxref("RegExp.test", "test")}} メソッドや、{{jsxref("String")}} の {{jsxref("String.match", "match")}}、 {{jsxref("String.matchAll", "matchAll")}}、{{jsxref("String.replace", "replace")}}、{{jsxref("String.search", "search")}}、および {{jsxref("String.split", "split")}} メソッドで使用できます。本章では、JavaScript の正規表現について説明します。</p> + +<h2 id="Creating_a_Regular_Expression" name="Creating_a_Regular_Expression">正規表現の作成</h2> + +<p>正規表現は 2 種類の方法で作成できます :</p> + +<p>次のように、スラッシュによって囲まれたパターンからなる正規表現リテラルを使用します :</p> + +<pre class="brush: js notranslate">var re = /ab+c/; +</pre> + +<p>正規表現リテラルはスクリプトのロード時にその正規表現をコンパイルします。正規表現が一定のままの場合、この方法を使うとよいパフォーマンスが得られます。</p> + +<p>また、次のように {{jsxref("RegExp")}} オブジェクトのコンストラクタ関数を呼び出す方法があります :</p> + +<pre class="brush: js notranslate">var re = new RegExp('ab+c'); +</pre> + +<p>コンストラクタ関数を使用すると、実行時にその正規表現をコンパイルします。正規表現パターンが変わることがわかっている場合や、パターンがわからない場合、ユーザーが入力するなど別のソースからパターンを取得する場合は、コンストラクタ関数を使用してください。</p> + +<h2 id="Writing_a_Regular_Expression_Pattern" name="Writing_a_Regular_Expression_Pattern">正規表現パターンの記述</h2> + +<p>正規表現パターンは、<code>/abc/</code> のような単純な文字、または <code>/ab*c/</code> や <code>/Chapter (\d+)\.\d*/</code> のような単純な文字と特殊文字との組み合わせからなります。最後の例には記憶装置として用いられる丸括弧があります。パターンのこの丸括弧で囲まれた部分でマッチした箇所は、後で使用できるように記憶されます。詳しくは{{anch("Using_Parenthesized_Substring_Matches", "括弧で囲まれた部分文字列のマッチの使用")}}を参照してください。</p> + +<h3 id="Using_Simple_Patterns" name="Using_Simple_Patterns">単純なパターンの使い方</h3> + +<p>単純なパターンとは、直接マッチしている部分を見つけたい文字から構成されたものです。例えば <code>/abc/</code> というパターンは、実際に 'abc' という文字が一緒にその順で存在しているときだけ、文字列中の文字の組み合わせにマッチします。"Hi, do you know your abc's?" や "The latest airplane designs evolved from slabcraft." といった文字列でのマッチは成功します。どちらの場合でも 'abc' という部分文字列にマッチします。"Grab crab" という文字列では、'abc' という部分文字列が含まれていないためマッチしません。</p> + +<h3 id="Using_Special_Characters" name="Using_Special_Characters">特殊文字の使い方</h3> + +<p>1 個以上の b を見つけたり、ホワイトスペースを見つけたりといった直接マッチより高度なマッチの検索では、パターンに特殊文字を使用します。例えば <code>/ab*c/</code> というパターンでは、1 個の 'a' とその後ろに続く 0 個以上の 'b' (<code>*</code> は直前のアイテムの 0 回以上の出現を意味します)、そしてそのすぐ後ろに続く 'c' で構成される文字の組み合わせにマッチします。"cbbabbbbcdebc," という文字列では、このパターンは 'abbbbc' という部分文字列にマッチします。</p> + +<p>以下のページで、正規表現で使用できる特殊文字の完全なリストとその意味を詳しく説明します。</p> + +<dl> + <dt><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">言明</a></dt> + <dd>言明には、 行や単語の始まり・終わりを示す、境界や、(先読み、後読み、条件式を含む)何らかの方法でマッチが可能なことを示す、その他のパターンが含まれます。</dd> + <dt><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">文字クラス</a></dt> + <dd>文字や数字の区別など、文字の種類を区別します。</dd> + <dt><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">グループと範囲</a></dt> + <dd>式にある文字のグループと範囲を示します。</dd> + <dt><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Quantifiers">数量詞</a></dt> + <dd>マッチする文字や式の数を示します。</dd> + <dt><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes">Unicode プロパティエスケープ</a></dt> + <dd>大文字と小文字、数学記号、句読点など、Unicode文字のプロパティに基づき区別します。</dd> +</dl> + +<p>正規表現で利用可能なすべての特殊文字を単一の表で見たい場合は、以下を参照してください。</p> + +<dl> + <dd> + <table class="standard-table"> + <caption>正規表現における特殊文字</caption> + <thead> + <tr> + <th scope="col">文字</th> + <th scope="col">意味</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="#special-backslash" id="special-backslash" name="special-backslash"><code>\</code></a></td> + <td> + <p>以下のルールに基づいてマッチします :</p> + + <p>特別な意味を持たない文字の前に付けられたバックスラッシュ文字は、次の文字が特別なもので、文字通りには評価されないことを表します。例えば、前に '\' がない '<code>b</code>' は文字列中のあらゆる箇所の小文字の 'b' にマッチします。つまり、その文字は文字通り評価されます。しかし '<code>\b</code>' という表現はどんな文字にもマッチしません。これは<a href="#special-word-boundary" title="#special-word-boundary">単語区切り</a>を意味します。<br> + <br> + 特別な意味を持つ文字の前に付けられたバックスラッシュ文字は、次の文字が特別なものでなく、文字通りに評価されることを表します。詳しくは "Escaping" の章を見てください。</p> + + <p>RegExp コンストラクタの引数に文字列を指定して使う場合、文字列リテラル内でのバックスラッシュはエスケープ文字であることを忘れないでください。つまり、パターン内でバックスラッシュを使うためには、文字列リテラル内でそれをエスケープする必要があるのです。 <code>/[a-z]\s/i</code> と <code>new RegExp("[a-z]\\s", "i")</code> は同じ正規表現を作成します。この表現は、A から Z までの範囲の任意の文字とそれに続く 1 つの空白を探します(<code>\s</code> は次以降を見てください)。文字列を引数として指定した新しい RegExp インスタンスで<em>リテラルとしての</em> バックスラッシュを表現するには、文字列レベルと正規表現レベルの両方でバックスラッシュをエスケープする必要があります。つまり、 <code>/[a-z]:\\/i</code> と <code>new RegExp("[a-z]:\\\\","i")</code> は "C:\" にマッチする同じ表現を作成します。</p> + </td> + </tr> + <tr> + <td><a href="#special-caret" id="special-caret" name="special-caret"><code>^</code></a></td> + <td> + <p>入力の先頭にマッチします。複数行フラグが true にセットされている場合は、改行文字の直後にもマッチします。<br> + <br> + 例えば、<code>/^A/</code> は "an A" の 'A' にはマッチしませんが、"An E" の 'A' にはマッチします。</p> + + <p>この文字は、文字集合パターンの先頭にある場合は異なる意味を持ちます。例と詳細については<a href="#special-negated-character-set">相補文字集合</a>をご覧ください。</p> + </td> + </tr> + <tr> + <td><a href="#special-dollar" id="special-dollar" name="special-dollar"><code>$</code></a></td> + <td> + <p>入力の末尾にマッチします。複数行フラグが true にセットされている場合は、改行文字の直前にもマッチします。</p> + + <p>例えば、<code>/t$/</code> は "eater" の 't' にはマッチしませんが、"eat" の 't' にはマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-asterisk" id="special-asterisk" name="special-asterisk"><code>*</code></a></td> + <td> + <p>直前の文字の 0 回以上の繰り返しにマッチします。<code>{0,}</code>に相当します。</p> + + <p>例えば、 <code>/bo*/</code> は "A ghost booooed" の 'boooo' や "A bird warbled" の 'b' にマッチしますが、"A goat grunted" ではマッチしません。</p> + </td> + </tr> + <tr> + <td><a href="#special-plus" id="special-plus" name="special-plus"><code>+</code></a></td> + <td> + <p>直前の文字の 1 回以上の繰り返しにマッチします。<code>{1,}</code>に相当します。</p> + + <p>例えば、<code>/a+/</code> は "candy" の 'a' や "caaaaaaandy" のすべての a にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-questionmark" id="special-questionmark" name="special-questionmark"><code>?</code></a></td> + <td>直前の文字の 0 回か 1 回の出現にマッチします。<code>{0,1}</code>に相当します。<br> + <br> + 例えば、 <code>/e?le?/</code> + <p>は "angel" の 'el' や "angle" の 'le'、あるいは "oslo" の 'l' にマッチします。</p> + *、+、?、{} といった量指定子の直後に使用した場合、その量指定子をデフォルトとは逆の{{原語併記("非貪欲","non-greedy")}} (最短)マッチにします。デフォルトは{{原語併記("欲張り","greedy")}}(最長)マッチです。例えば、<code>/\d+/</code> は "123abc" の "123" にマッチしますが、<code>/\d+?/</code> の場合は "1" にだけマッチします。<br> + <br> + この特殊文字は、この表の <code>x(?=y)</code> および <code>x(?!y)</code> + + <p>の項目で説明する先読みアサーションでも使用できます。</p> + </td> + </tr> + <tr> + <td><a href="#special-dot" id="special-dot" name="special-dot"><code>.</code></a></td> + <td> + <p>(小数点) はデフォルトでは改行文字以外のどの 1 文字にもマッチします。</p> + + <p>例えば、 <code>/.n/</code> は "nay, an apple is on the tree" の 'an' や 'on' にはマッチしますが、'nay' にはマッチしません。</p> + + <p><code>s</code> ("dotAll") フラグが true にセットされている場合は、改行文字にもマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-capturing-parentheses" id="special-capturing-parentheses" name="special-capturing-parentheses"><code>(x)</code></a></td> + <td> + <p>'x' にマッチし、マッチした内容を記憶します。この括弧は<em>キャプチャリング(格納)括弧</em>と呼ばれます。<br> + <br> + 例えば、パターン<code>/(foo) (bar)\1 \2/</code>内の '<code>(foo)</code>' と '<code>(bar)</code>' は、文字列 "foo bar foo bar" の最初の 2 個の単語にマッチし、それを記憶します。パターン内の <code>\1</code> と<code>\2</code> の 1 個目と 2 個目の括弧内の文字、すなわち <code>foo</code> と <code>bar</code>を表し、文字列の最後の 2 個の単語にマッチします。<code>\1</code>, <code>\2</code>, ..., <code>\n</code> は正規表現のマッチ部分で使用することに注意してください。詳しくは下記の <a href="#special-backreference">\n</a> を参照してください。 置換部分で使用する際は <code>$1</code>, <code>$2</code>, ..., <code>$n</code> とする必要があります。例えば、 <code>'bar foo'.replace(/(...) (...)/, '$2 $1')</code>というように。<code>$&</code> はマッチした文字列全体を意味します。</p> + </td> + </tr> + <tr> + <td><a href="#special-non-capturing-parentheses" id="special-non-capturing-parentheses" name="special-non-capturing-parentheses"><code>(?:x)</code></a></td> + <td> + <p>'x' にマッチしますが、マッチした内容は記憶しません。この括弧は<em>非キャプチャリング(非格納)括弧</em>と呼ばれ、パターンをグルーピングして、正規表現演算子と一緒に使う際の部分正規表現式を定義することができます。 見本として式 <code>/(?:foo){1,2}/</code> を見てみましょう。式が <code>/foo{1,2}/</code>であれば、<code>{1,2}</code> の文字は 'foo' の最後の 'o' にのみ適用されます。非キャプチャリング括弧を使うと、<code>{1,2}</code> は'foo' という単語全体に適用されます。詳しい情報は、下記の<a href="#Using_Parentheses">括弧を使う</a>を見てください。</p> + </td> + </tr> + <tr> + <td><a href="#special-lookahead" id="special-lookahead" name="special-lookahead"><code>x(?=y)</code></a></td> + <td> + <p>'x' に 'y' が続く場合のみ 'x' にマッチします。この特殊文字は先読みと呼ばれます。</p> + + <p>例えば、<code>/Jack(?=Sprat)/</code> は 'Jack' の後に 'Sprat' が続く場合のみ 'Jack' にマッチします。 <code>/Jack(?=Sprat|Frost)/</code> は 'Jack' の後ろに 'Sprat' または 'Frost' が続く場合のみ 'Jack' にマッチします。しかしながら、'Sprat' も 'Frost' もマッチの結果には表れません。</p> + </td> + </tr> + <tr> + <td><a href="#special-negated-look-ahead" id="special-negated-look-ahead" name="special-negated-look-ahead"><code>x(?!y)</code></a></td> + <td> + <p>'x' に 'y' が続かない場合のみ 'x' にマッチします。これは否定先読みと呼ばれます。</p> + + <p>例えば、 <code>/\d+(?!\.)/</code> は後ろに小数点が続かない数値にマッチします。正規表現 <code>/\d+(?!\.)/.exec("3.141")</code> は'141' にマッチしますが '3.141' にはマッチしません。</p> + </td> + </tr> + <tr> + <td><a href="#special-lookbehind" id="special-lookbehind" name="special-lookbehind"><code>(?<=y)x</code></a></td> + <td> + <p><code><em>x</em></code> の前に <code>y</code> がある場合のみ<code><em>x</em></code>にマッチします。 これは後読みと呼ばれます。</p> + + <p>例えば、 <code>/(?<=Jack)Sprat/</code> は "Sprat" の前に "Jack" がある場合にのみマッチし、<br> + <code>/(?<=Jack|Tom)Sprat/</code> は "Sprat" の前に "Jack" または "Tom" がある場合にのみマッチします。<br> + しかしながら、"Jack"も "Tom" もマッチの結果には表れません。</p> + </td> + </tr> + <tr> + <td><a href="#special-negative-lookbehind" id="special-negative-lookbehind" name="special-negative-lookbehind"><code>(?<!y)x</code></a></td> + <td> + <p><code><em>x</em></code> の前に <code><em>y</em></code>がない場合のみ <code><em>x</em></code> にマッチします。これは否定後読みと呼ばれます。</p> + + <p>例えば、 <code>/(?<!-)\d+/</code> は前にマイナス符号がない数値にのみマッチします。<br> + <code>/(?<!-)\d+/.exec('3')</code> は "3"にマッチしていますが、<br> + <code>/(?<!-)\d+/.exec('-3')</code> にマッチは見つかりません。なぜなら' -3' の前にはマイナス符号があるからです。</p> + </td> + </tr> + <tr> + <td><a href="#special-or" id="special-or" name="special-or"><code>x|y</code></a></td> + <td> + <p>'x', または 'y' にマッチします。('x' にマッチする必要はありません。)</p> + + <p>例えば、<code>/green|red/</code> は "green apple" の 'green' や "red apple." の 'red' にマッチします。'x' と 'y' の順番は重要です。例えば <code>a*|b</code> は"b" の空文字列にマッチしますが、 <code>b|a*</code> は同じ文字列の "b" にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-quantifier" id="special-quantifier" name="special-quantifier"><code>{n}</code></a></td> + <td>直前の文字がちょうど n 回出現するものにマッチします。n には正の整数が入ります。<br> + <br> + 例えば、 <code>/a{2}/</code> は "candy" の 'a' にはマッチしませんが、"caaandy" の最初の 2 個の a にはマッチします。</td> + </tr> + <tr> + <td><a href="#special-quantifier" id="special-quantifier" name="special-quantifier"><code>{n,}</code></a></td> + <td> + <p>直前の式の少なくとも n 回の出現にマッチします。n には正の整数が入ります。</p> + + <p>例えば、 <code>/a{2,}/</code> は "aa", "aaaa", "aaaaa" にマッチしますが "a" にはマッチしません。</p> + </td> + </tr> + <tr> + <td><a href="#special-quantifier-range" id="special-quantifier-range" name="special-quantifier-range"><code>{n,m}</code></a></td> + <td> + <p>直前の文字が少なくとも <code>n</code> 回、多くても <code>m</code> 回出現するものにマッチします。<code>n</code> および <code>m</code> には正の整数が入ります。<code>m</code> を省略した場合は ∞ とみなされます。</p> + + <p>例えば、 <code>/a{1,3}/</code> は "cndy" ではマッチせず、"candy," の 'a'、"caandy," の 最初の 2 個の a、"caaaaaaandy" の最初の 3 個の a にマッチします。"caaaaaaandy" では元の文字列に a が 4 個以上ありますが、マッチするのは "aaa" であることに注意してください。</p> + </td> + </tr> + <tr> + <td><a href="#special-character-set" id="special-character-set" name="special-character-set"><code>[xyz]</code></a></td> + <td> + <p>文字集合を表します。このパターンでは、角括弧で囲まれた文字のいずれか 1 個にマッチします。対象の文字は<a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Using_special_characters_in_strings" title="JavaScript Guide: Grammar and types § Using special characters in strings">エスケープシーケンス</a>も含みます。 文字の集合内では、特殊文字 (例えばドット (<code>.</code>) やアスタリスク (<code>*</code>)) は特別な意味を持たないので、それらにエスケープは不要です。以下で例示するように、ハイフンを用いて文字の範囲を指定することも可能です。<br> + <br> + 例えば <code>[abcd]</code> は <code>[a-d]</code> と同じです。これは "brisket" の 'b' や "city" の 'c' にマッチします。<code>/[a-z.]+/</code> および <code>/[\w.]+/</code> はどちらも、"test.i.ng" の全体にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-negated-character-set" id="special-negated-character-set" name="special-negated-character-set"><code>[^xyz]</code></a></td> + <td> + <p>文字集合の否定または補集合です。角括弧で囲まれた文字ではない文字にマッチします。ハイフンを用いて文字の範囲を指定することも可能です。文字集合パターンで動作するものすべてがこちらでも機能します。</p> + + <p>例えば、 <code>[^abc]</code> は <code>[^a-c]</code>と同じです。これは "brisket" の 'r' や "chop" の 'h' といった一番最初の該当文字にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-backspace" id="special-backspace" name="special-backspace"><code>[\b]</code></a></td> + <td>後退文字(バックスペース、U+0008)にマッチします。 後退文字自体にマッチさせるには角括弧を使う必要があります。(<code>\b</code> と混同しないように。)</td> + </tr> + <tr> + <td><a href="#special-word-boundary" id="special-word-boundary" name="special-word-boundary"><code>\b</code></a></td> + <td> + <p>単語の区切りにマッチします。単語の区切りは、単語構成文字と後に続く非単語構成文字の間、または非単語構成文字と後に続く単語構成文字の間、または文字列の先頭、または文字列の最後とマッチします。単語の区切りはマッチする「文字」ではありません。アンカーのように、単語の区切りはマッチした部分に含まれません。言い換えると、マッチした単語の区切りの長さは 0 です。(<code>[\b]</code> と混同してはいけません。)</p> + + <p>入力文字に "moon" を使用した例:<br> + <code>/\bm/</code> はマッチします。これは `\b` が文字列の先頭に存在するからです。<br> + <code>/oo\b/</code> の '\b' はマッチしません。これは '\b' の前後に単語構成文字があるためです。<br> + <code>/oon\b/</code> の '\b' はマッチします。これは、文字列の終端であるためです。<br> + <code>/\w\b\w/</code> の '\b' はどこにもマッチしないでしょう。これは、'\b' の前後に単語構成文字があるためです。</p> + + <div class="note"> + <p><strong>注記 :</strong> JavaScript の正規表現エンジンでは「{{原語併記("単語","word")}}」を構成する文字として <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15.10.2.6">特定の文字集合</a>を定義しています。 この集合内にない文字は非単語構成文字と見なされます。この文字集合はかなり限定的なもので、ローマ字の大文字小文字のアルファベット、10 進数字とアンダースコアのみが含まれます。"é" や "ü" といった文字{{訳注("そして日本語を構成する文字たちも")}}、残念ながら、一般的な表意文字と同様に、単語の区切りのために非単語構成文字として扱われます。</p> + </div> + </td> + </tr> + <tr> + <td><a href="#special-non-word-boundary" id="special-non-word-boundary" name="special-non-word-boundary"><code>\B</code></a></td> + <td> + <p>単語の区切り以外にマッチします。マッチするのは以下の場合です:</p> + + <ul> + <li>文字列の先頭の文字の前</li> + <li>文字列の終端の文字の後</li> + <li>単語内の 2 文字の間</li> + <li>2 つの単語ではない文字の間</li> + <li>空文字列</li> + </ul> + + <p>例えば、<code>/\B../</code> は "noonday" の 'oo' に、<code>/y\B./</code> は "possibly yesterday" の 'ye' にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-control" id="special-control" name="special-control"><code>\c<em>X</em></code></a></td> + <td> + <p>文字列中の制御文字にマッチします。 <em>X</em> には A から Z のうち 1 文字が入ります。</p> + + <p>例えば、 <code>/\cM/</code> は文字列中の control-M (U+000D) にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-digit" id="special-digit" name="special-digit"><code>\d</code></a></td> + <td> + <p>数字にマッチします。<code>[0-9]</code> に相当します。</p> + + <p>例えば、 <code>/\d/</code> や <code>/[0-9]/</code> は "B2 is the suite number" の '2' にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-non-digit" id="special-non-digit" name="special-non-digit"><code>\D</code></a></td> + <td> + <p>数字以外の文字にマッチします。<code>[^0-9]</code> に相当します。</p> + + <p>例えば、<code>/\D/</code> や<code>/[^0-9]/</code> は "B2 is the suite number" の 'B' にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-form-feed" id="special-form-feed" name="special-form-feed"><code>\f</code></a></td> + <td>改ページ (U+000C) にマッチします。</td> + </tr> + <tr> + <td><a href="#special-line-feed" id="special-line-feed" name="special-line-feed"><code>\n</code></a></td> + <td>改行文字 (U+000A) にマッチします。</td> + </tr> + <tr> + <td><a href="#special-carriage-return" id="special-carriage-return" name="special-carriage-return"><code>\r</code></a></td> + <td>復帰文字 (U+000D) にマッチします。</td> + </tr> + <tr> + <td><a href="#special-white-space" id="special-white-space" name="special-white-space"><code>\s</code></a></td> + <td> + <p>スペース、タブ、改ページ、改行を含むホワイトスペース文字にマッチします。<code>[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]</code> に相当します。</p> + + <p>例えば <code>/\s\w*/</code> は "foo bar" の ' bar' にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-non-white-space" id="special-non-white-space" name="special-non-white-space"><code>\S</code></a></td> + <td> + <p>ホワイトスペース以外の文字にマッチします。 <code>[^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]</code> に相当します。</p> + + <p>例えば、 <code>/\S*/</code> は "foo bar" の 'foo' にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-tab" id="special-tab" name="special-tab"><code>\t</code></a></td> + <td>タブ (U+0009) にマッチします。</td> + </tr> + <tr> + <td><a href="#special-vertical-tab" id="special-vertical-tab" name="special-vertical-tab"><code>\v</code></a></td> + <td>垂直タブ (U+000B) にマッチします。</td> + </tr> + <tr> + <td><a href="#special-word" id="special-word" name="special-word"><code>\w</code></a></td> + <td> + <p>アンダースコアを含むどの英数字にもマッチします。<code>[A-Za-z0-9_]</code> に相当します。</p> + + <p>例えば <code>/\w/</code> は、"apple," の 'a' や "$5.28," の '5' や "3D" の '3' にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-non-word" id="special-non-word" name="special-non-word"><code>\W</code></a></td> + <td> + <p>前述以外の文字にマッチします。<code>[^A-Za-z0-9_]</code> に相当します。</p> + + <p>例えば、<code>/\w/</code> や <code>/[^A-Za-z0-9_]/</code> は、"50%" の '%' にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-backreference" id="special-backreference" name="special-backreference"><code>\<em>n</em></code></a></td> + <td> + <p><em>n</em> に正の整数が入る場合、正規表現内において <em>n</em> 番目の括弧の部分にマッチした最新の部分文字列への後方参照となります(括弧の数は左からカウントします)。</p> + + <p>例えば <code>/apple(,)\sorange\1/</code> は "apple, orange, cherry, peach" の 'apple, orange,' にマッチします。</p> + </td> + </tr> + <tr> + <td><a href="#special-null" id="special-null" name="special-null"><code>\0</code></a></td> + <td>NULL 文字 (U+0000) にマッチします。この後ろに他の数字を続けてはいけません。<code>\0</code> の後に(0 から 7 までの)数字が続くと 8 進数の <a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Using_special_characters_in_strings" title="JavaScript Guide: Grammar and types § Using special characters in strings">エスケープシーケンス</a>となるからです。</td> + </tr> + <tr> + <td><a href="#special-hex-escape" id="special-hex-escape" name="special-hex-escape"><code>\xhh</code></a></td> + <td>hh(2 桁の 16 進数)コードからなる文字列にマッチします。</td> + </tr> + <tr> + <td><a href="#special-unicode-escape" id="special-unicode-escape" name="special-unicode-escape"><code>\uhhhh</code></a></td> + <td>hhhh(4 桁の 16 進数)コードからなる文字列にマッチします。</td> + </tr> + <tr> + <td><a href="#special-unicode-escape-es6" id="special-unicode-escape-es6" name="special-unicode-escape-es6"><code>\u{hhhh}</code></a></td> + <td>(u フラグがセットされた時のみ) Unicode 値 hhhh (16 進数) からなる文字列にマッチします。</td> + </tr> + </tbody> + </table> + </dd> + <dt></dt> +</dl> + +<h3 id="Escaping" name="Escaping">エスケープする</h3> + +<p>もし特殊な文字を使う必要があるのなら(例えば実際に * を検索したい場合)、その文字の前にバックスラッシュを付けてエスケープする必要があります。例えば、a と * と b が続くのを検索する場合、<code>/a\*b/</code> とします。これはバックスラッシュが * を特殊な文字ではなく、リテラルとして扱うようにエスケープしています。</p> + +<p>同様に、もし正規表現リテラルを書いていてスラッシュ('/')とマッチさせる必要があるならば、スラッシュをエスケープする必要があります(そうしないとスラッシュがパターンを終了してしまいます)。例えば、"/example/"の文字列とそれに続く1つ以上のアルファベットを探すためには、<code>/\/example\/[a-z]+/i</code> とします。各スラッシュ前のバックスラッシュが、スラッシュをリテラルにしています。</p> + +<p>リテラルのバックスラッシュにマッチするためには、バックスラッシュをエスケープする必要があります。例えば、'C' は任意の文字である "C:\" という文字列にマッチするためには、<code>/[A-Z]:\\/</code>とします。最初のバックスラッシュはその後のバックスラッシュをエスケープし、この表現は単一のリテラルバックスラッシュを探します。</p> + +<p>RegExp コンストラクタを文字列リテラルを引数に指定して利用する場合は、バックスラッシュは文字列リテラル内でのエスケープ文字であることを思い出してください。つまり、バックスラッシュを正規表現で用いるには文字列リテラルレベルでエスケープする必要があります。 <code>/a\*b/</code> と <code>new RegExp("a\\*b")</code> は、 'a' の次に '*'、その次に 'b' を探す同じ表現を作成します。</p> + +<p>エスケープ文字がパターンに追加されてないなら、{{jsxref("String.replace")}} を使用して追加することができます:</p> + +<pre class="brush: js notranslate">function escapeRegExp(string) { + return string.replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&'); // $&はマッチした部分文字列全体を意味します +}</pre> + +<p>正規表現の後の g はグローバルサーチを行うオプション/フラグで、全体の文字列を見てすべてのマッチを返します。下の{{anch("Advanced_Searching_With_Flags", "フラグを用いた高度な検索")}}に詳しく説明されています。</p> + +<h3 id="Using_Parentheses" name="Using_Parentheses">括弧の使い方</h3> + +<p>正規表現パターンの一部を括弧で囲むことで、マッチした部分文字列を記憶しておくことができます。いったん記憶されれば、後からその部分文字列を呼び出すことができます。これに関しては{{anch("Using_Parenthesized_Substring_Matches", "括弧で囲まれた部分文字列のマッチの使用")}}で説明しています。</p> + +<p>例として <code>/Chapter (\d+)\.\d*/</code> というパターンを使い、エスケープ文字と特殊文字についても説明した上で、どのようにパターンの一部が記憶されるかを示します。これは 'Chapter ' という文字列に正確にマッチし、それに続く 1 文字以上の数字 (<code>\d</code> はいずれかの数字を、<code>+</code> は 1 回以上の繰り返しを意味します)、それに続く小数点(それ自体は特殊文字であり、小数点の前の \ はパターンが '.' という文字そのものを探すようにすることを意味します)、それに続く 0 文字以上の数字 (<code>\d</code> は数字を、<code>*</code> は 0 回以上の繰り返しを意味します)にマッチします。さらに、最初にマッチした数字の記憶に括弧が使われています。</p> + +<p>このパターンは "Open Chapter 4.3, paragraph 6" という文字列で検索され、'4' が記憶されます。このパターンは "Chapter 3 and 4" では見つかりません。この文字列は '3' の後にピリオドがないからです。</p> + +<p>マッチした部分を記憶させることなく部分文字列にマッチさせたい場合は、その括弧においてパターンの前に <code>?:</code> をつけてください。例えば <code>(?:\d+)</code> は 1 文字以上の数字にマッチしますが、マッチした文字列は記憶しません。</p> + +<h2 id="Working_with_Regular_Expressions" name="Working_with_Regular_Expressions">JavaScriptでの正規表現の使い方</h2> + +<p>正規表現は、<code>RegExp</code> の <code>test</code> および <code>exec</code> メソッド、<code>String</code> の <code>match</code>、<code>replace</code>、<code>search</code>、<code>split</code> メソッドとともに使用します。これらのメソッドの詳細は <a href="/ja/docs/JavaScript/Reference">JavaScript リファレンス</a>で説明しています。</p> + +<table class="standard-table"> + <caption>正規表現を使用するメソッド</caption> + <thead> + <tr> + <th scope="col">メソッド</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("RegExp.exec", "exec")}}</td> + <td>文字列中で一致するものを検索する <code>RegExp</code> のメソッドです。結果情報の配列を返します。</td> + </tr> + <tr> + <td>{{jsxref("RegExp.test", "test")}}</td> + <td>文字列中で一致するものがあるかをテストする <code>RegExp</code> のメソッドです。true または false を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.match", "match")}}</td> + <td>文字列中で一致するものを検索する <code>String</code> のメソッドです。結果情報の配列を返します。マッチしない場合は null を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.matchAll", "matchAll")}}</td> + <td>キャプチャグループを含んだ、すべてのマッチをもつ iterator を返す <code>String</code> のメソッドです。 </td> + </tr> + <tr> + <td>{{jsxref("String.search", "search")}}</td> + <td>文字列中で一致するものがあるかをテストする <code>String</code> のメソッドです。マッチした場所のインデックスを返します。検索に失敗した場合は -1 を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.replace", "replace")}}</td> + <td>文字列中で一致するものを検索し、マッチした部分文字列を別の部分文字列に置換する <code>String</code> のメソッドです。</td> + </tr> + <tr> + <td>{{jsxref("String.split", "split")}}</td> + <td>正規表現または固定文字列を用いて文字列を分割し、部分文字列の配列に入れる <code>String</code> のメソッドです。</td> + </tr> + </tbody> +</table> + +<p>あるパターンが文字列に存在するかを知りたいときは、<code>test</code> または <code>search</code> メソッドを使用してください。詳細な情報が知りたいときは(実行時間が長くなりますが)<code>exec</code> または <code>match</code> メソッドを使用してください。<code>exec</code> や <code>match</code> を使用してマッチが成功した場合、これらのメソッドは配列を返し、また結びつけられた正規表現オブジェクトと定義済みオブジェクトである <code>RegExp</code> オブジェクトのプロパティを更新します。マッチが失敗すると、<code>exec</code> メソッドは <code>null</code>(<code>false</code> に変換します)を返します。</p> + +<p>次の例では、<code>exec</code> メソッドを使用して文字列を検索します。</p> + +<pre class="brush: js notranslate">var myRe = /d(b+)d/g; +var myArray = myRe.exec("cdbbdbsbz"); +</pre> + +<p>正規表現のプロパティにアクセスする必要がない場合は、次のスクリプトが <code>myArray</code> を作成する別の方法になります:</p> + +<pre class="brush: js line-numbers notranslate">var myArray = /d(b+)d/g.exec('cdbbdbsbz'); // similar to "cdbbdbsbz".match(/d(b+)d/g); however, + // the latter outputs Array [ "dbbd" ], while + // /d(b+)d/g.exec('cdbbdbsbz') outputs Array [ 'dbbd', 'bb', index: 1, input: 'cdbbdbsbz' ].</pre> + +<p>(異なるふるまいの詳しい情報は {{anch("g-different-behaviors", "g フラグによる振る舞いの違い")}}を参照してください。)</p> + +<p>ある文字列から正規表現を組み立てたい場合は、次のスクリプトのような方法があります:</p> + +<pre class="brush: js notranslate">var myRe = new RegExp('d(b+)d', 'g'); +var myArray = myRe.exec('cdbbdbsbz'); +</pre> + +<p>これらのスクリプトではマッチが成功すると、配列を返すとともに次表で示されるプロパティを更新します。</p> + +<table class="standard-table"> + <caption>正規表現の実行結果</caption> + <thead> + <tr> + <th scope="col">オブジェクト</th> + <th scope="col">プロパティまたはインデックス</th> + <th scope="col">説明</th> + <th scope="col">この例の場合</th> + </tr> + </thead> + <tbody> + <tr> + <td rowspan="4"><code>myArray</code></td> + <td></td> + <td>マッチした文字列と、すべての記憶された部分文字列です。</td> + <td><code>['dbbd', 'bb', index: 1, input: 'cdbbdbsbz']</code></td> + </tr> + <tr> + <td><code>index</code></td> + <td>入力文字列でマッチした位置を示す、0 から始まるインデックスです。</td> + <td><code>1</code></td> + </tr> + <tr> + <td><code>input</code></td> + <td>元の文字列です。</td> + <td><code>"cdbbdbsbz"</code></td> + </tr> + <tr> + <td><code>[0]</code></td> + <td>最後にマッチした文字列です。</td> + <td><code>"dbbd"</code></td> + </tr> + <tr> + <td rowspan="2"><code>myRe</code></td> + <td><code>lastIndex</code></td> + <td>次のマッチが始まるインデックスです。(このプロパティは、g オプションを用いる正規表現でのみセットされます。これについては{{anch("Advanced_Searching_With_Flags", "フラグを用いた高度な検索")}}で説明します。)</td> + <td><code>5</code></td> + </tr> + <tr> + <td><code>source</code></td> + <td>パターンのテキストです。正規表現の実行時ではなく作成時に更新されます。</td> + <td><code>"d(b+)d"</code></td> + </tr> + </tbody> +</table> + +<p>この例の 2 つ目の形式で示したように、オブジェクト初期化子を使用して、変数に代入せずに正規表現を使うことができます。しかしながら、この方法では生成される正規表現はすべて、別の正規表現として作成されます。このため、変数に代入しないこの形式を使用する場合は、その正規表現のプロパティに後からアクセスすることができません。例えば、次のようなスクリプトを使用するとしましょう :</p> + +<pre class="brush: js notranslate">var myRe = /d(b+)d/g; +var myArray = myRe.exec('cdbbdbsbz'); +console.log('The value of lastIndex is ' + myRe.lastIndex); + +// "The value of lastIndex is 5" +</pre> + +<p>しかし、このスクリプトの場合は次のようになります:</p> + +<pre class="brush: js line-numbers notranslate">var myArray = /d(b+)d/g.exec('cdbbdbsbz'); +console.log('The value of lastIndex is ' + /d(b+)d/g.lastIndex); + +// "The value of lastIndex is 0"</pre> + +<p>この 2 つの文中の <code>/d(b+)d/g</code> は別の正規表現オブジェクトであり、そのためにそれぞれの <code>lastIndex</code> プロパティの値も異なるのです。オブジェクト初期化子で作成する正規表現のプロパティにアクセスする必要がある場合は、まずそれを変数に代入するようにしてください。</p> + +<h3 id="Using_Parenthesized_Substring_Matches" name="Using_Parenthesized_Substring_Matches">括弧で囲まれた部分文字列のマッチの使用</h3> + +<p>正規表現パターンに括弧を含めることで、対応するサブマッチが記憶されます。例えば <code>/a(b)c/</code> は 'abc' という文字列にマッチし、'b' が記憶されます。この括弧で囲まれた部分文字列のマッチは、<code>Array</code> の要素 <code>[1]</code>, ..., <code>[n]</code> を使用して呼び出すことができます。</p> + +<p>括弧で囲まれた部分文字列は何個でも使用できます。返された配列には、見つかったものすべてが存在します。以下の例では、括弧で囲まれた部分文字列の使用法を説明します。</p> + +<p>次のスクリプトは {{jsxref("String.replace", "replace()")}} メソッドを使用して文字列中の単語を入れ替えます。テキスト置き換えのために、スクリプトで <code>$1</code> と <code>$2</code> を使用して、最初とその次の括弧で囲まれた部分文字列のマッチを示しています。</p> + +<pre class="brush: js notranslate">var re = /(\w+)\s(\w+)/; +var str = 'John Smith'; +var newstr = str.replace(re, '$2, $1'); +console.log(newstr); + +// "Smith, John" +</pre> + +<h3 id="Advanced_Searching_With_Flags" name="Advanced_Searching_With_Flags">フラグを用いた高度な検索</h3> + +<p>正規表現には、グローバルな検索や大文字/小文字を区別しない検索を可能にする 4 種類のオプションフラグがあります。これらのフラグは、単独で使用することもまとめて使用することもできます。順番は問いません。フラグは正規表現の一部として含まれます。</p> + +<table class="standard-table"> + <caption>正規表現フラグ</caption> + <thead> + <tr> + <th scope="col">フラグ</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>g</code></td> + <td>グローバルサーチ。</td> + </tr> + <tr> + <td><code>i</code></td> + <td>大文字・小文字を区別しない検索。</td> + </tr> + <tr> + <td><code>m</code></td> + <td>複数行検索。</td> + </tr> + <tr> + <td><code>s</code></td> + <td><code>.</code> を改行文字と一致するようにします。</td> + </tr> + <tr> + <td><code>u</code></td> + <td>"unicode"; パターンをユニコードのコードポイントの連続として扱う</td> + </tr> + <tr> + <td><code>y</code></td> + <td>対象文字列で最後に見つかったマッチの位置から検索を開始する{{原語併記("先頭固定","sticky")}} 検索を行います。{{jsxref("RegExp.sticky", "sticky")}} のページをご覧ください。</td> + </tr> + </tbody> +</table> + +<p>フラグを正規表現に含めるには、次のようにしてください :</p> + +<pre class="brush: js notranslate">var re = /pattern/flags; +</pre> + +<p>または</p> + +<pre class="brush: js notranslate">var re = new RegExp('pattern', 'flags'); +</pre> + +<p>フラグは正規表現を作る際になくてはならないものであることに注意してください。後から加えたり取り除いたりすることはできません。</p> + +<p>例えば <code>re = /\w+\s/g</code> は、1 個以上の文字とそれに続くスペースを探す正規表現を作成します。また、正規表現は文字列全体を通してこの組み合わせを探します。</p> + +<pre class="brush: js notranslate">var re = /\w+\s/g; +var str = 'fee fi fo fum'; +var myArray = str.match(re); +console.log(myArray); + +// ["fee ", "fi ", "fo "] +</pre> + +<p>この例では次の行 :</p> + +<pre class="brush: js notranslate">var re = /\w+\s/g; +</pre> + +<p>を次の行 :</p> + +<pre class="brush: js notranslate">var re = new RegExp('\\w+\\s', 'g'); +</pre> + +<p>に置き換えることができます。得られる結果は同じです。</p> + +<p id="g-different-behaviors"><code>.exec()</code> メソッドが使われた時には '<strong><code>g</code></strong>' に関連したふるまいは異なります。("class" と "argument" の役割が反対になります: <code>.match()</code> の場合、文字クラス(やデータ型) がメソッドを持ち、正規表現は単なる引数で、<code>.exec()</code> の場合、正規表現がメソッドを持ち、文字は引数です。<em><code>str.match(re)</code></em> と <em><code>re.exec(str)</code></em> を比較します) '<code><strong>g</strong></code>' フラグが <strong><code>.exec()</code></strong> メソッドで使われる時は繰り返して進むためです。</p> + +<pre class="brush: js line-numbers notranslate">var xArray; while(xArray = re.exec(str)) console.log(xArray); +// produces: +// ["fee ", index: 0, input: "fee fi fo fum"] +// ["fi ", index: 4, input: "fee fi fo fum"] +// ["fo ", index: 7, input: "fee fi fo fum"]</pre> + +<p><code>m</code> フラグは複数行の入力文字列が複数行として扱われるように使われます。<code>m</code> が使われた場合、<code>^</code> と <code>$</code> は文字列全体の最初と最後の代わりに、入力文字列内のあらゆる行の開始と終了にマッチします。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<p>以下では、正規表現の使用法をいくつか例示します。</p> + +<h3 id="Changing_the_Order_in_an_Input_String" name="Changing_the_Order_in_an_Input_String">入力文字列の順序変更</h3> + +<p>次の例では、正規表現の構造と <code>string.split()</code> および <code>string.replace()</code> の使用法を示します。空白、タブ、1 個のセミコロンで分割された名前(ファーストネームが先頭)からなる、大まかに整形された入力文字列をきれいにフォーマットします。最終的に名前の順序を逆転し(ラストネームが先頭)、リストをソートします。</p> + +<pre class="brush: js line-numbers language-js notranslate">// 名前の文字列は複数の空白やタブを含む。 +// また、ファーストネームとラストネームの間に複数の空白があることもある +var names = 'Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand '; + +var output = ['---------- Original String\n', names + '\n']; + +// 2 種類の正規表現パターンと、格納用の配列を用意する。 +// 文字列を分割して配列の要素に収める。 + +// パターン: ホワイトスペースの 0 回以上の繰り返しのあとにセミコロン、そのあとにホワイトスペースの 0 回以上の繰り返し +var pattern = /\s*;\s*/; + +// 上記のパターンで文字列を断片に分割し、 +// nameList という配列に断片を格納する。 +var nameList = names.split(pattern); + +// 新たなパターン: 1 個以上の文字、1 個以上のホワイトスペース、1 個以上の文字 +// 括弧を用いてパターンの断片を記憶する。 +// 記憶した断片は後から参照される。 +pattern = /(\w+)\s+(\w+)/; + +// 処理された名前を格納する新しい配列。 +var bySurnameList = []; + +// 名前の配列を表示し、新しい配列にカンマ区切りで名前を +// ラストネーム、ファーストネームの順で格納する。 +// +// replace メソッドはパターンにマッチしたものを除去し、 +// 「2 番目の記憶文字列のあとにカンマとスペース、 +// さらにその後に続く 1 番目の記憶文字列」に置き換える。 +// +// 変数 $1 および $2 は、パターンにマッチさせた際に +// 記憶しておいた部分文字列を参照する + +output.push('---------- After Split by Regular Expression'); + +var i, len; +for (i = 0, len = nameList.length; i < len; i++){ + output.push(nameList[i]); + bySurnameList[i] = nameList[i].replace(pattern, '$2, $1'); +} + +// 新しい配列を表示する。 +output.push("---------- Names Reversed"); +for (i = 0, len = bySurnameList.length; i < len; i++){ + output.push(bySurnameList[i]); +} + +// ラストネームについてソートし、ソートした配列を表示する。 +bySurnameList.sort(); +output.push('---------- Sorted'); +for (i = 0, len = bySurnameList.length; i < len; i++){ + output.push(bySurnameList[i]); +} + +output.push('---------- End'); + +console.log(output.join('\n')); + +// produces: +// +// ---------- Original String +// +// Orange Carrot ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand +// +// ---------- After Split by Regular Expression +// Orange Carrot +// Fred Barney +// Helen Rigby +// Bill Abel +// Chris Hand +// ---------- Names Reversed +// Carrot, Orange +// Barney, Fred +// Rigby, Helen +// Abel, Bill +// Hand, Chris +// ---------- Sorted +// Abel, Bill +// Barney, Fred +// Carrot, Orange +// Hand, Chris +// Rigby, Helen +// ---------- End + +</pre> + +<h3 id="Using_Special_Characters_to_Verify_Input" name="Using_Special_Characters_to_Verify_Input">特殊文字を用いた入力の確認</h3> + +<p>次の例では、ユーザーは電話番号を入力します。ユーザーが "Check" ボタンを押すと、スクリプトがその番号の妥当性を確認します。その番号が正当である(正規表現で指定した文字の連続にマッチする)場合、スクリプトはユーザーへの感謝のメッセージを表示し、その番号を承認します。番号が正当でない場合は、その番号が妥当でないことをユーザーに通知します。</p> + +<p>正規表現は、0 または 1 個の左括弧 <code>\(?</code>、その後に 3 個の数字 <code>\d{3}</code>、その後に 0 または 1 個の右括弧 <code>\)?</code>、その後、見つかった際に記憶される 1 個のダッシュ、スラッシュ、または小数点 <code>([-\/\.])</code>、その後に 3 個の数字 <code>\d{3}</code>、その後、記憶された 1 個のダッシュ、スラッシュ、または小数点のマッチ <code>\1</code>、その後に 4 個の数字 <code>\d{4}</code> を探します。</p> + +<p>ユーザーが <code>Enter</code> ボタンを押した際に発動する <code>Change</code> イベントにより <code>RegExp.input</code> の値が設定されます。</p> + +<h4 id="HTML">HTML</h4> + +<pre class="brush: html notranslate"><p> + 電話番号(市外局番含む)を入力して "チェック" をクリックしてください。 + <br> + 適切な形式は ###-###-#### のようなものです。 +</p> +<form action="#"> + <input id="phone"> + <button onclick="testInfo(document.getElementById('phone'));">チェック</button> +</form></pre> + +<h4 id="JavaScript">JavaScript</h4> + +<pre class="brush: js notranslate">var re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/; +function testInfo(phoneInput) { + var OK = re.exec(phoneInput.value); + if (!OK) { + console.error(phoneInput.value + ' は市外局番付電話番号ではありません!'); + } else { + console.log('ありがとう、あなたの電話番号は ' + OK[0]);} +} </pre> + +<h4 id="結果">結果</h4> + +<div> +<p>{{ EmbedLiveSample('Using_Special_Characters_to_Verify_Input', '', '', '', 'Web/JavaScript/Guide/Regular_Expressions') }}</p> + +<h2 id="仕様">仕様</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様</th> + <th scope="col">策定状況</th> + <th scope="col">コメント</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-regexp-regular-expression-objects', 'RegExp')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="ブラウザサポート">ブラウザサポート</h2> + +<div> + + +<p>{{Compat("javascript.builtins.RegExp")}}</p> +</div> +</div> + +<div>{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}</div> diff --git a/files/ja/web/javascript/guide/regular_expressions/quantifiers/index.html b/files/ja/web/javascript/guide/regular_expressions/quantifiers/index.html new file mode 100644 index 0000000000..273fc82ff1 --- /dev/null +++ b/files/ja/web/javascript/guide/regular_expressions/quantifiers/index.html @@ -0,0 +1,152 @@ +--- +title: 数量詞 +slug: Web/JavaScript/Guide/Regular_Expressions/Quantifiers +tags: + - JavaScript + - Reference + - Regular Expressions + - quantifiers + - regex +translation_of: Web/JavaScript/Guide/Regular_Expressions/Quantifiers +--- +<p>{{jsSidebar("JavaScript Guide")}}{{draft}}</p> + +<p>数量詞はマッチする文字や式の数を示します。</p> + +<h2 id="Types" name="Types">種類</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">文字</th> + <th scope="col">意味</th> + </tr> + </thead> + <tbody> + <tr> + <td><code><em>x</em>*</code></td> + <td> + <p>直前の文字 <em>x</em> の 0 回以上の繰り返しにマッチします。例えば <code>/bo*/</code> は "A ghost booooed" の "boooo" や "A bird warbled" の "b" にマッチしますが、"A goat grunted" ではマッチしません。</p> + </td> + </tr> + <tr> + <td><code><em>x</em>+</code></td> + <td> + <p>直前の文字 <em>x</em> の 1 回以上の繰り返しにマッチします。<code>{1,}</code> に相当します。例えば <code>/a+/</code> は "candy" の "a" や "caaaaaaandy" のすべての "a" にマッチします。</p> + </td> + </tr> + <tr> + <td><code><em>x</em>?</code></td> + <td> + <p>直前の文字 <em>x</em> の 0 回か 1 回の出現にマッチします。例えば <code>/e?le?/</code> は "angel" の "el" や "angle" の "le"、あるいは "oslo" の "l" にマッチします。</p> + + <p><code>*</code>、<code>+</code>、<code>?</code>、<code>{}</code> といった量指定子の直後に使用した場合、その量指定子をデフォルトとは逆の{{原語併記("非貪欲", "non-greedy")}} (最短)マッチにします。デフォルトは{{原語併記("欲張り", "greedy")}}(最長)マッチです。</p> + </td> + </tr> + <tr> + <td><code><em>x</em>{<em>n</em>}</code></td> + <td> + <p><code>n</code> には正の整数が入ります。直前の文字 <em>x</em> がちょうど <code>n</code> 回出現するものにマッチします。例えば <code>/a{2}/</code> は "candy" の "a" にはマッチしませんが、"caaandy" の最初の 2 個の "a" にはマッチします。</p> + </td> + </tr> + <tr> + <td><code><em>x</em>{<em>n</em>,}</code></td> + <td> + <p><code>n</code> には正の整数が入ります。直前の文字 <em>x</em> の少なくとも <code>n</code> 回の出現にマッチします。例えば、<code>/a{2,}/</code> は "candy" の "a" にはマッチしませんが、"caandy" や "caaaaaaandy" の "a" のすべてにマッチします。</p> + </td> + </tr> + <tr> + <td><code><em>x</em>{<em>n</em>,<em>m</em>}</code></td> + <td> + <p><code>n</code> には 0 と正の整数が、<code>m</code> には <code>n</code> より大きい正の整数が入ります。直前の文字 <em>x</em> が少なくとも <code>n</code> 回、多くても <code>m</code> 回出現するものにマッチします。例えば <code>/a{1,3}/</code> は "cndy" ではマッチせず、"candy" の 'a'、"caandy" の 最初の 2 個の "a"、"caaaaaaandy" の最初の 3 個の "a" にマッチします。"caaaaaaandy" では元の文字列に "a" が 4 個以上ありますが、マッチするのは "aaa" であることに注意してください。</p> + </td> + </tr> + <tr> + <td> + <p><code><em>x</em>*?</code><br> + <code><em>x</em>+?</code><br> + <code><em>x</em>??</code><br> + <code><em>x</em>{n}?</code><br> + <code><em>x</em>{n,}?</code><br> + <code><em>x</em>{n,m}?</code></p> + </td> + <td> + <p>既定では <code>*</code> や <code>+</code> といった数量詞は{{原語併記("貪欲", "greedy")}} です。つまり、できる限り多くの文字列とマッチしようとします。数量詞の後にある <code>?</code> 文字は{{原語併記("非貪欲", "non-greedy")}} 数量詞をつくります: つまり、マッチが見つかるとすぐに停止します。例えば、"some <foo> <bar> new </bar> </foo> thing" といった文字列が与えられたなら:</p> + + <ul> + <li><code>/<.*>/</code> はおそらく "<foo> <bar> new </bar> </foo>" にマッチするでしょう</li> + <li><code>/<.*?>/</code> はおそらく "<foo>" にマッチするでしょう</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<h2 id="例">例</h2> + +<h3 id="任意の文字">任意の文字</h3> + +<pre class="brush: js">var britishText = "He asked his neighbour a favour."; +var americanText = "He asked his neighbor a favor."; + +var regexpEnding = /\w+ou?r/g; +// \w+ 1つ以上の文字 +// o "o" が続く +// u? 任意で "u" が続く +// r "r" が続く + +console.table(britishText.match(regexpEnding)); +// ["neighbour", "favour"] + +console.table(americanText.match(regexpEnding)); +// ["neighbor", "favor"] +</pre> + +<h3 id="貪欲と非貪欲の比較">貪欲と非貪欲の比較</h3> + +<pre class="brush: js">var text = "I must be getting somewhere near the centre of the earth."; +var greedyRegexp = /[\w ]+/; +// [\w ] ラテンアルファベットまたは空白 +// + 1回以上 + +console.log(text.match(greedyRegexp)[0]); +// "I must be getting somewhere near the centre of the earth." +// テキストのすべてがマッチ + +var nonGreedyRegexp = /[\w ]+?/; // クエスチョンマークに注目 +console.log(text.match(nonGreedyRegexp)); +// "I" +// マッチは可能なもので最小 +</pre> + +<h2 id="仕様">仕様</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様</th> + <th scope="col">策定状況</th> + <th scope="col">コメント</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-quantifier', 'RegExp: Quantifiers')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="ブラウザサポート">ブラウザサポート</h2> + +<div> + + +<p>{{Compat("javascript.builtins.RegExp.quantifiers")}}</p> +</div> + +<h2 id="関連情報">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions">正規表現</a></li> + <li><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp"><code>RegExp()</code> コンストラクタ</a></li> +</ul> diff --git a/files/ja/web/javascript/guide/text_formatting/index.html b/files/ja/web/javascript/guide/text_formatting/index.html new file mode 100644 index 0000000000..9df0e489e9 --- /dev/null +++ b/files/ja/web/javascript/guide/text_formatting/index.html @@ -0,0 +1,256 @@ +--- +title: テキスト処理 +slug: Web/JavaScript/Guide/Text_formatting +tags: + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Text_formatting +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}</div> + +<p class="summary">本章では JavaScript で文字列やテキストを操作する方法を紹介します。</p> + +<h2 id="Strings" name="Strings">文字列</h2> + +<p>JavaScript の{{Glossary("String","文字列")}}型はテキストデータを表すために使われます。テキストデータ型は 16 ビット符号なし整数値 (UTF-16) からなる「要素」の集合体です。文字列の各要素は、その文字列内で所定の位置を占めています。最初の要素のインデックスは 0 で、次の要素のインデックスは 1 、といった具合に。文字列の長さはその要素数となります。文字列リテラルか文字列オブジェクトを使用して文字列を生成できます。</p> + +<div class="hidden">CAUTION: if you edit this page, do not include any characters above U+FFFF, until MDN bug 857438 is fixed ( <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=857438">https://bugzilla.mozilla.org/show_bug.cgi?id=857438</a> ).</div> + +<h3 id="String_literals" name="String_literals">文字列リテラル</h3> + +<p>単一引用符または二重引用符のいずれかを使用して、単純な文字列を作成できます :</p> + +<pre class="brush: js notranslate">'foo' +"bar"</pre> + +<p>また、エスケープシーケンスを使用してより高度な文字列を作成できます :</p> + +<h4 id="Hexadecimal_escape_sequences" name="Hexadecimal_escape_sequences">16 進数エスケープシーケンス</h4> + +<p><code>\x</code> の後の数値は <a href="https://ja.wikipedia.org/wiki/十六進法">16 進法による</a>数として解釈されます。</p> + +<pre class="brush: js notranslate">'\xA9' // "©" +</pre> + +<h4 id="Unicode_escape_sequences" name="Unicode_escape_sequences">Unicode エスケープシーケンス</h4> + +<p>Unicode エスケープシーケンスは <code>\u</code> の後に少なくとも文字が 4 個必要です。</p> + +<pre class="brush: js notranslate">'\u00A9' // "©"</pre> + +<h4 id="Unicode_code_point_escapes" name="Unicode_code_point_escapes">Unicode コードポイントエスケープ</h4> + +<p>ECMAScript 2015 の新機能です。Unicode コードポイントエスケープを使えば、どんな文字でも 16 進数を使用してエスケープすることができます。これにより、<code>0x10FFFF</code> まで Unicode コードポイントを利用できます。単純な Unicode エスケープを使用して同じ結果を得るには、多くの場合要素を半分に分け、サロゲートペアにする必要があります。</p> + +<p>{{jsxref("String.fromCodePoint()")}} や {{jsxref("String.prototype.codePointAt()")}} も参考にしてください。</p> + +<pre class="brush: js notranslate">'\u{2F804}' + +// 単純な Unicode エスケープでも同じです。 +'\uD87E\uDC04'</pre> + +<h3 id="String_objects" name="String_objects">String オブジェクト</h3> + +<p>{{jsxref("String")}} オブジェクトは文字列プリミティブデータ型のためのラッパです。</p> + +<pre class="brush: js notranslate">const foo = new String('foo'); // 文字列オブジェクトを作る +console.log(foo); // Displays: [String: 'foo'] +typeof foo; // Returns 'object' +</pre> + +<p>文字列リテラル値に対しても <code>String</code> オブジェクトのメソッドを呼び出すことができます ― JavaScript は自動的に文字列リテラルを一時的な <code>String</code> オブジェクトに変換し、メソッドを呼び出し、そして一時的に作られた <code>String</code> オブジェクトを破棄します。文字列リテラルでは <code>String.length</code> プロパティも利用できます。</p> + +<p><code>String</code> オブジェクトを使用する明確な必要性がなければ、文字列リテラルを使用してください。というのも、<code>String</code> オブジェクトは直感的でない振る舞いをします。例えば :</p> + +<pre class="brush: js notranslate">const firstString = '2 + 2'; // 文字列リテラル値を作成 +const secondString = new String('2 + 2'); // 文字列オブジェクトを作成 +eval(firstString); // 数値の 4 を返す +eval(secondString); // 文字列 "2 + 2" を返す</pre> + +<p><code>String</code> オブジェクトのプロパティの 1 つには、文字列内の UTF-16 コード単位の数を示す <code>length</code> があります。例えば、次のコードでは、<code>helloLength</code> には値 13 が代入されます。"Hello, World!" は 13 文字で、それぞれが 1 つの UTF-16 コード単位で表されるからです。配列の角括弧書式を使用して、各コード単位にアクセスできます。文字列は不変の配列のようなオブジェクトなので、個々の文字を変更することはできません:</p> + +<pre class="brush: js notranslate">const hello = 'Hello, World!'; +const helloLength = hello.length; +hello[0] = 'L'; // 文字列は不変なので、これは効果がありません +hello[0]; // これは "H" を返します +</pre> + +<p>Unicode のスカラー値が U+FFFF より大きい文字 (中国語/日本語/韓国語/ベトナム語の特殊な文字や絵文字など) は、それぞれ 2 つのサロゲートコード単位で UTF-16 に格納されます。たとえば、単一の文字 U+1F600 (笑顔の絵文字) から成る文字列の長さは 2 になります。このような文字列の括弧で囲まれた個々のコード単位にアクセスすると、一致しないサロゲートコード単位の文字列が生成されるなど、Unicode 標準違反という好ましくない結果になります。(その例は、MDN のバグ 857438 が修正された後にこのページに追加する必要があります。) {{jsxref("String.fromCodePoint()")}} または{{jsxref("String.prototype.codePointAt()")}} も参照してください。</p> + +<p><code>String</code> オブジェクトはさまざまなメソッドを持っています。例えば、<code>substring</code> や <code>toUpperCase</code> のような文字列自体のバリエーションを返すメソッドがあります。</p> + +<p>次の表は {{jsxref("String")}} オブジェクトのメソッドをまとめたものです。</p> + +<table class="standard-table"> + <caption> + <h4 id="Methods_of_String" name="Methods_of_String"><code>String</code> のメソッド</h4> + </caption> + <thead> + <tr> + <th scope="col">メソッド</th> + <th scope="col">説明</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("String.charAt", "charAt")}}、{{jsxref("String.charCodeAt", "charCodeAt")}}、{{jsxref("String.codePointAt", "codePointAt")}}</td> + <td>文字列内の指定された位置の文字または文字コードを返します。</td> + </tr> + <tr> + <td>{{jsxref("String.indexOf", "indexOf")}}, {{jsxref("String.lastIndexOf", "lastIndexOf")}}</td> + <td>それぞれ、文字列内にある指定された部分文字列の先頭位置、および末尾の位置を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.startsWith", "startsWith")}}, {{jsxref("String.endsWith", "endsWith")}}, {{jsxref("String.includes", "includes")}}</td> + <td>文字列が指定した文字列で始まるか、終わるか、それを含むかどうかを返します。</td> + </tr> + <tr> + <td>{{jsxref("String.concat", "concat")}}</td> + <td>2 つの文字列をテキストとしてつなげた新しい文字列を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.fromCharCode", "fromCharCode")}}, {{jsxref("String.fromCodePoint", "fromCodePoint")}}</td> + <td>指定の Unicode 値シーケンスから文字列を構築します。これは、<code>String</code> インスタンスではなく、<code>String</code> クラスにあるメソッドです。</td> + </tr> + <tr> + <td>{{jsxref("String.split", "split")}}</td> + <td>文字列を部分文字列へと分けることで、<code>String</code> オブジェクトを文字列の配列に分割します。</td> + </tr> + <tr> + <td>{{jsxref("String.slice", "slice")}}</td> + <td>文字列の一部分を取り出し、新しい文字列を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.substring", "substring")}}, {{jsxref("String.substr", "substr")}}</td> + <td>開始インデックスから終了インデックスまで、または開始インデックスと長さ、このいずれかを指定することで文字列における特定の部分集合を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.match", "match")}}, {{jsxref("String.matchAll", "matchAll")}}, {{jsxref("String.replace", "replace")}}, {{jsxref("String.replaceAll", "replaceAll")}}, {{jsxref("String.search", "search")}}</td> + <td>正規表現と共に機能します。</td> + </tr> + <tr> + <td>{{jsxref("String.toLowerCase", "toLowerCase")}}, {{jsxref("String.toUpperCase", "toUpperCase")}}</td> + <td> + <p>それぞれ、すべて小文字またはすべて大文字にした文字列を返します。</p> + </td> + </tr> + <tr> + <td>{{jsxref("String.normalize", "normalize")}}</td> + <td>呼び出し元となる文字列値の Unicode 正規化形式を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.repeat", "repeat")}}</td> + <td>所定回数繰り返したオブジェクト要素からなる文字列を返します。</td> + </tr> + <tr> + <td>{{jsxref("String.trim", "trim")}}</td> + <td>文字列の先頭と末尾から空白文字を取り除きます。</td> + </tr> + </tbody> +</table> + +<h3 id="Multi-line_template_strings" name="Multi-line_template_strings">マルチラインテンプレート文字列</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/template_strings">テンプレート文字列</a>は式を埋め込むことができる文字列リテラルです。複数行の文字列や文字列の補間機能で使用することができます。</p> + +<p>テンプレート文字列は二重引用符または一重引用符のかわりにバックティック (` `) (<a class="external external-icon" href="https://en.wikipedia.org/wiki/Grave_accent">抑音アクセント</a>)文字で囲まれています。テンプレート文字列にはプレースホルダーを含めることができます。プレースホルダーはドル記号と波括弧 (<code>${expression}</code>) によって示されます。</p> + +<h4 id="Multi-lines" name="Multi-lines">マルチライン</h4> + +<p>ソースに挿入されたいかなる改行文字も、テンプレート文字列の一部となります。通常の文字列を使って複数行の文字列を取得するには、次のような構文を使用しなければなりません :</p> + +<pre class="brush: js notranslate">console.log('string text line 1\n\ +string text line 2'); +// "string text line 1 +// string text line 2"</pre> + +<p>複数行の文字列と同じ結果を得たければ、テンプレート文字列を使って下記のように書くことができます :</p> + +<pre class="brush: js notranslate">console.log(`string text line 1 +string text line 2`); +// "string text line 1 +// string text line 2"</pre> + +<h4 id="Embedded_expressions" name="Embedded_expressions">組み込み式</h4> + +<p>通常の文字列内に式を埋め込むには、次のような構文を用います :</p> + +<pre class="brush: js notranslate">const five = 5; +const ten = 10; +console.log('Fifteen is ' + (five + ten) + ' and not ' + (2 * five + ten) + '.'); +// "Fifteen is 15 and not 20."</pre> + +<p>テンプレート文字列を使えば、糖衣構文を利用してこれをより読みやすくすることができます。:</p> + +<pre class="brush: js notranslate">const five = 5; +const ten = 10; +console.log(`Fifteen is ${five + ten} and not ${2 * five + ten}.`); +// "Fifteen is 15 and not 20."</pre> + +<p>詳細については、<a href="/ja/docs/Web/JavaScript/Reference">JavaScript リファレンス</a>内の<a href="/ja/docs/Web/JavaScript/Reference/template_strings">テンプレート文字列</a>をご覧ください。</p> + +<h2 id="Internationalization" name="Internationalization">国際化</h2> + +<p>{{jsxref("Intl")}} オブジェクトは ECMAScript 国際化 API のための名前空間です。ECMAScript 国際化 API は、各言語に応じた文字列比較、数値フォーマット、日時フォーマットを提供します。{{jsxref("Collator")}}、{{jsxref("NumberFormat")}}、{{jsxref("DateTimeFormat")}} オブジェクトのコンストラクタは <code>Intl</code> オブジェクトのプロパティとなっています。</p> + +<h3 id="Date_and_time_formatting" name="Date_and_time_formatting">日時フォーマット</h3> + +<p>{{jsxref("DateTimeFormat")}} オブジェクトは日時をフォーマットするのに便利です。次の例では、日付をアメリカ英語のフォーマットにします(結果は別のタイムゾーンで異なります)。</p> + +<pre class="brush: js notranslate">const msPerDay = 24 * 60 * 60 * 1000; + +// July 17, 2014 00:00:00 UTC. +const july172014 = new Date(msPerDay * (44 * 365 + 11 + 197)); + +const options = { year: '2-digit', month: '2-digit', day: '2-digit', + hour: '2-digit', minute: '2-digit', timeZoneName: 'short' }; +const americanDateTime = new Intl.DateTimeFormat('en-US', options).format; + +console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT +</pre> + +<h3 id="Number_formatting" name="Number_formatting">数値フォーマット</h3> + +<p>{{jsxref("NumberFormat")}} オブジェクトは数値、例えば通貨をフォーマットするのに有用です。</p> + +<pre class="brush: js notranslate">const gasPrice = new Intl.NumberFormat('en-US', + { style: 'currency', currency: 'USD', + minimumFractionDigits: 3 }); + +console.log(gasPrice.format(5.259)); // $5.259 + +const hanDecimalRMBInChina = new Intl.NumberFormat('zh-CN-u-nu-hanidec', + { style: 'currency', currency: 'CNY' }); + +console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五 +</pre> + + +<h3 id="Collation" name="Collation">照合</h3> + +<p>{{jsxref("Collator")}} オブジェクトは文字列を比較しソートするのに便利です。</p> + +<p>例えば、ドイツ語には二つの異なるソート順、<em>phonebook</em>(電話帳順)と <em>dictionary</em>(辞書順)が存在します。電話帳順ソートは音を強調し、ソート前に “ä”、“ö” といった文字があたかも “ae”、“oe” などであるかのように解釈されます。</p> + +<pre class="brush: js notranslate">const names = ['Hochberg', 'Hönigswald', 'Holzman']; + +const germanPhonebook = new Intl.Collator('de-DE-u-co-phonebk'); + +// ["Hochberg", "Hoenigswald", "Holzman"] としてソートされる: +console.log(names.sort(germanPhonebook.compare).join(', ')); +// "Hochberg, Hönigswald, Holzman" がログ出力される +</pre> + +<p>ドイツ語の単語の中にはウムラウト記号によって変化するものがあるため、辞書順では(<em>schön</em> の前は <em>schon</em> といったような、ウムラウトのみ異なるような単語をソートする場合を除けば)ウムラウトを無視してソートするのが賢明です。</p> + +<pre class="brush: js notranslate">const germanDictionary = new Intl.Collator('de-DE-u-co-dict'); + +// ["Hochberg", "Honigswald", "Holzman"] としてソートされる: +console.log(names.sort(germanDictionary.compare).join(', ')); +// "Hochberg, Holzman, Hönigswald" とログ出力される +</pre> + +<p>{{jsxref("Intl")}} API の詳細については、<a href="https://hacks.mozilla.org/2014/12/introducing-the-javascript-internationalization-api/">Introducing the JavaScript Internationalization API</a> もご覧ください。</p> + +<div>{{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}</div> diff --git a/files/ja/web/javascript/guide/the_employee_example/creating_the_hierarchy/index.html b/files/ja/web/javascript/guide/the_employee_example/creating_the_hierarchy/index.html new file mode 100644 index 0000000000..2340536ff7 --- /dev/null +++ b/files/ja/web/javascript/guide/the_employee_example/creating_the_hierarchy/index.html @@ -0,0 +1,134 @@ +--- +title: Creating the Hierarchy +slug: Web/JavaScript/Guide/The_Employee_Example/Creating_the_Hierarchy +--- +<h3 id=".E9.9A.8E.E5.B1.A4.E3.81.AE.E4.BD.9C.E6.88.90" name=".E9.9A.8E.E5.B1.A4.E3.81.AE.E4.BD.9C.E6.88.90">階層の作成</h3> +<p>Employee の階層を実装するための適当なコンストラクタ関数を定義する方法はいくつかあります。これの定義に何を選択するかは、アプリケーションで何ができるようにしたいかに大きくよります。</p> +<p>このセクションではとても単純(かつ比較的柔軟でない)定義の使用方法を示し、継承を機能させる方法を実際に示します。これらの定義では、オブジェクト作成時に何らかのプロパティの値を指定することはできません。新しく作成されるオブジェクトは単にデフォルトの値を取得するだけです。これは後から変更できます。図 8.2 ではこれらの単純な定義を備えた階層を例示します。</p> +<p>実際のアプリケーションでは、オブジェクト作成時にプロパティの値を設定できるようにするコンストラクタを定義することになるでしょう(詳しくは <a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/More_Flexible_Constructors" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/More_Flexible_Constructors">より柔軟なコンストラクタ</a> を参照)。今回はこれらの単純な定義を使用して、継承はどのようにして起こるのかを実際に示していくことにします。</p> +<p><img alt="Image:hier02.gif" class="internal" src="/@api/deki/files/1905/=Hier02.gif"><br> + <small><strong>図 8.2:Employee オブジェクトの定義</strong></small></p> +<p>以下に示すように、Java と JavaScript の <code>Employee</code> の定義は似ています。唯一の相違点は、Java では各プロパティに対して型を指定する必要があるのに対して、JavaScript ではその必要がないことです。また、Java のクラスでは明示的なコンストラクタメソッドを作成する必要があります。</p> +<table class="fullwidth-table"> + <tbody> + <tr> + <th>JavaScript</th> + <th>Java</th> + </tr> + <tr> + <td> + <pre> +function Employee () { +this.name = ""; +this.dept = "general"; +} +</pre> + </td> + <td> + <pre> +public class Employee { + public String name; + public String dept; + public Employee () { + this.name = ""; + this.dept = "general"; + } +} +</pre> + </td> + </tr> + </tbody> +</table> +<p><code>Manager</code> および <code>WorkerBee</code> の定義では、継承の連鎖において上である次のオブジェクトの指定方法に違いがあります。JavaScript では原型的なインスタンスをコンストラクタ関数の <code>prototype</code> プロパティとして追加します。コンストラクタを定義した後ならいつでもそれをすることができます。Java ではクラス定義内でスーパークラスを指定します。クラス定義の外部でスーパークラスを変更することはできません。</p> +<table class="fullwidth-table"> + <tbody> + <tr> + <th>JavaScript</th> + <th>Java</th> + </tr> + <tr> + <td> + <pre> +function Manager () { +this.reports = []; +} +Manager.prototype = new Employee; + +function WorkerBee () { +this.projects = []; +} +WorkerBee.prototype = new Employee; +</pre> + </td> + <td> + <pre> +public class Manager extends Employee { + public Employee[] reports; + public Manager () { + this.reports = new Employee[0]; + } +} + +public class WorkerBee extends Employee { + public String[] projects; + public WorkerBee () { + this.projects = new String[0]; + } +} +</pre> + </td> + </tr> + </tbody> +</table> +<p><code>Engineer</code> および <code>SalesPerson</code> の定義は、<code>WorkerBee</code> の子孫、それゆえに <code>Employee</code> の子孫であるオブジェクトを作成します。これらの種類のオブジェクトは連鎖において上にある全オブジェクトのプロパティを持ちます。さらに、これらの定義は <code>dept</code> プロパティの継承された値をこれらのオブジェクト固有の新しい値で上書きします。</p> +<table class="fullwidth-table"> + <tbody> + <tr> + <th>JavaScript</th> + <th>Java</th> + </tr> + <tr> + <td> + <pre> +function SalesPerson () { + this.dept = "sales"; + this.quota = 100; +} +SalesPerson.prototype = new WorkerBee; + +function Engineer () { + this.dept = "engineering"; + this.machine = ""; +} +Engineer.prototype = new WorkerBee; +</pre> + </td> + <td> + <pre> +public class SalesPerson extends WorkerBee { + public double quota; + public SalesPerson () { + this.dept = "sales"; + this.quota = 100.0; + } +} + +public class Engineer extends WorkerBee { + public String machine; + public Engineer () { + this.dept = "engineering"; + this.machine = ""; + } +} +</pre> + </td> + </tr> + </tbody> +</table> +<p>これらの定義を使用して、そのプロパティのデフォルト値を取得するこれらのオブジェクトのインスタンスを作成することができます。図 8.3 ではこれらの JavaScript の定義を使用して新しいオブジェクトを作成する方法を示しています。また、新しいオブジェクトに対するプロパティの値も示しています。</p> +<p><strong>注意</strong>:<em>インスタンス</em>という用語はクラスベース言語においてはある特定の技術的な意味を持っています。これらの言語では、インスタンスとはクラスの個々のメンバであり、クラスとは根本的に異なるものです。JavaScript では「インスタンス」はこの技術的な意味を持っていません。なぜならば JavaScript にはクラスとインスタンスとの間のこの違いがないからです。しかしながら、JavaScript について話す際に、「インスタンス」をある特定のコンストラクタ関数を用いて作成したオブジェクトを意味する言葉として正式ではない形で使用することがあります。例えば、<code>jane</code> は <code>Engineer</code> のインスタンスであると砕けた言い方をすることもできます。同様に、<em>親</em>、<em>子</em>、<em>祖先</em>、そして<em>子孫</em>という用語は JavaScript において正式な意味を持ちませんが、プロトタイプチェーンにおいて上や下にあるオブジェクトについて言及する際にそれらを正式ではない形で使用してもかまいません。</p> +<p><img alt="Image:hier03.gif" class="internal" src="/@api/deki/files/1906/=Hier03.gif"><br> + <small><strong>図 8.3:単純な定義を用いたオブジェクトの作成</strong></small></p> +<div class="noinclude"> + <p>{{ PreviousNext("Core_JavaScript_1.5_Guide:The_Employee_Example", "Core_JavaScript_1.5_Guide:The_Employee_Example:Object_Properties") }}</p> +</div> diff --git a/files/ja/web/javascript/guide/the_employee_example/index.html b/files/ja/web/javascript/guide/the_employee_example/index.html new file mode 100644 index 0000000000..63176fa7e2 --- /dev/null +++ b/files/ja/web/javascript/guide/the_employee_example/index.html @@ -0,0 +1,31 @@ +--- +title: The Employee Example +slug: Web/JavaScript/Guide/The_Employee_Example +--- +<h3 id=".E5.BE.93.E6.A5.AD.E5.93.A1.E3.81.AE.E4.BE.8B" name=".E5.BE.93.E6.A5.AD.E5.93.A1.E3.81.AE.E4.BE.8B">従業員の例</h3> +<p>この章の残りは次の図で示す従業員の階層を使用していきます。</p> +<p><img alt="Image:hier01.gif" class="internal" src="/@api/deki/files/1904/=Hier01.gif"></p> +<p><small><strong>図 8.1:単純なオブジェクト階層</strong></small></p> +<p>これの例では以下のオブジェクトを使用しています。</p> +<ul> + <li>Employee はプロパティ name(デフォルトの値は空文字列)および dept(デフォルトの値は "general")を持つ。</li> + <li>Manager は Employee をベースとしている。これは reports プロパティ(デフォルトの値は空の配列、その値として Employee オブジェクトの配列を持たせる)を追加する。</li> + <li>WorkerBee も Employee をベースとしている。これは projects プロパティ(デフォルトの値は空の配列、その値として文字列の配列を持たせる)を追加する。</li> + <li>SalesPerson は WorkerBee をベースとしている。これは quota プロパティ(デフォルトの値は 100)を追加する。さらに dept プロパティを "sales" という値で上書きする。これは販売員は全員同じ部署に所属していることを示す。</li> + <li>Engineer は WorkerBee をベースとしている。これは machine プロパティ(デフォルトの値は空文字列)を追加し、さらに dept プロパティを "engineering" という値で上書きする。</li> +</ul> +<p>残りの例:</p> +<ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Creating_the_Hierarchy" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Creating_the_Hierarchy">階層の作成</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties">オブジェクトのプロパティ</a> + <ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Inheriting_Properties" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Inheriting_Properties">プロパティの継承</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Adding_Properties" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Adding_Properties">プロパティの追加</a></li> + </ul> + </li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/More_Flexible_Constructors" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/More_Flexible_Constructors">より柔軟なコンストラクタ</a></li> +</ul> +<div class="noinclude"> + <p>{{ PreviousNext("Core_JavaScript_1.5_Guide:Class-Based_vs._Prototype-Based_Languages", "Core_JavaScript_1.5_Guide:The_Employee_Example:Creating_the_Hierarchy") }}</p> +</div> +<p> </p> diff --git a/files/ja/web/javascript/guide/the_employee_example/object_properties/adding_properties/index.html b/files/ja/web/javascript/guide/the_employee_example/object_properties/adding_properties/index.html new file mode 100644 index 0000000000..c6d536602b --- /dev/null +++ b/files/ja/web/javascript/guide/the_employee_example/object_properties/adding_properties/index.html @@ -0,0 +1,19 @@ +--- +title: Adding Properties +slug: Web/JavaScript/Guide/The_Employee_Example/Object_Properties/Adding_Properties +--- +<h3 id=".E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E8.BF.BD.E5.8A.A0" name=".E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E8.BF.BD.E5.8A.A0">プロパティの追加</h3> +<p>JavaScript では実行時にどんなオブジェクトにもプロパティを追加することができます。コンストラクタ関数で与えられるプロパティだけを使う必要はありません。ある 1 つのオブジェクト固有のプロパティを追加するには、次のようにしてオブジェクトに値を代入します。</p> +<pre>mark.bonus = 3000; +</pre> +<p>すると、<code>mark</code> オブジェクトには bonus プロパティができます。しかし、他のどの <code>WorkerBee</code> にもこのプロパティは存在しません。</p> +<p>あるコンストラクタ関数に対するプロトタイプとして使用されているオブジェクトに新しいプロパティを追加する場合、プロトタイプからプロパティを継承する全オブジェクトへそのプロパティを追加することになります。例えば、次の文を使用すると <code>specialty</code> プロパティをすべての従業員に対して追加することができます。</p> +<pre>Employee.prototype.specialty = "none"; +</pre> +<p>JavaScript がこの文を実行するとすぐに <code>mark</code> オブジェクトも "<code>none</code>" という値を持つ specialty プロパティを持つようになります。次の図ではこのプロパティを Employee プロトタイプに追加し、さらに <code>Engineer</code> プロトタイプに対するそれを上書きしたときの効果を示します。</p> +<p><img alt="Image:hier04.gif" class="internal" src="/@api/deki/files/1907/=Hier04.gif"><br> + <small><strong>図 8.4:プロパティの追加</strong></small></p> +<div class="noinclude"> + <p>{{ PreviousNext("Core_JavaScript_1.5_Guide:The_Employee_Example:Object_Properties:Inheriting_Properties", "Core_JavaScript_1.5_Guide:The_Employee_Example:More_Flexible_Constructors") }}</p> +</div> +<p> </p> diff --git a/files/ja/web/javascript/guide/the_employee_example/object_properties/index.html b/files/ja/web/javascript/guide/the_employee_example/object_properties/index.html new file mode 100644 index 0000000000..e529b8bb52 --- /dev/null +++ b/files/ja/web/javascript/guide/the_employee_example/object_properties/index.html @@ -0,0 +1,13 @@ +--- +title: Object Properties +slug: Web/JavaScript/Guide/The_Employee_Example/Object_Properties +--- +<h3 id=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AE.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3" name=".E3.82.AA.E3.83.96.E3.82.B8.E3.82.A7.E3.82.AF.E3.83.88.E3.81.AE.E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3">オブジェクトのプロパティ</h3> +<p>このセクションでは、プロトタイプチェーンにおいてオブジェクトが他のオブジェクトからどのようにプロパティを継承するのか、また、実行時にプロパティを追加すると何が起きるのかについて論じます。</p> +<ul> + <li><a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Inheriting_Properties" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Inheriting_Properties">プロパティの継承</a></li> + <li><a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Adding_Properties" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Adding_Properties">プロパティの追加</a></li> +</ul> +<div class="noinclude"> + <p>{{ PreviousNext("Core_JavaScript_1.5_Guide:The_Employee_Example:Creating_the_Hierarchy", "Core_JavaScript_1.5_Guide:The_Employee_Example:Object_Properties:Inheriting_Properties") }}</p> +</div> diff --git a/files/ja/web/javascript/guide/the_employee_example/object_properties/inheriting_properties/index.html b/files/ja/web/javascript/guide/the_employee_example/object_properties/inheriting_properties/index.html new file mode 100644 index 0000000000..798746ead6 --- /dev/null +++ b/files/ja/web/javascript/guide/the_employee_example/object_properties/inheriting_properties/index.html @@ -0,0 +1,24 @@ +--- +title: Inheriting Properties +slug: >- + Web/JavaScript/Guide/The_Employee_Example/Object_Properties/Inheriting_Properties +--- +<h3 id=".E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E7.B6.99.E6.89.BF" name=".E3.83.97.E3.83.AD.E3.83.91.E3.83.86.E3.82.A3.E3.81.AE.E7.B6.99.E6.89.BF">プロパティの継承</h3> +<p>次の文を用いて(<a href="/ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Creating_the_Hierarchy" title="ja/Core_JavaScript_1.5_Guide/The_Employee_Example/Creating_the_Hierarchy">図 8.3</a> で示したように)<code>mark</code> オブジェクトを <code>WorkerBee</code> として作成するとします。</p> +<pre class="eval">mark = new WorkerBee; +</pre> +<p>JavaScript は new 演算子に出くわすと、新しく汎用オブジェクトを生成し、この新しいオブジェクトを <code>this</code> キーワードの値として WorkerBee コンストラクタ関数に渡します。コンストラクタ関数は明示的に <code>projects</code> プロパティの値をセットします。さらに、内部的な <code>__proto__</code> プロパティの値として <code>WorkerBee.prototype</code> の値をセットします。(このプロパティ名は最初と最後に 2 文字ずつのアンダースコアが付いています。)<code>__proto__</code> プロパティはプロパティの値を返すのに使用されるプロトタイプチェーンを決定します。これらのプロパティがセットされると JavaScript は新しいオブジェクトを返し、代入文は変数 <code>mark</code> にそのオブジェクトをセットします。</p> +<p>このプロセスでは <code>mark</code> がプロトタイプチェーンから継承するプロパティとして明示的には <code>mark</code> オブジェクトに値(<em>ローカルの</em>値)を格納しません。プロパティの値を使用するとき、JavaScript はまずその値がそのオブジェクトに存在しているかどうかを確認します。存在している場合はその値が返されます。値がローカルには存在していない場合、JavaScript はプロトタイプチェーンを確認します(<code>__proto__</code> プロパティを使用)。プロトタイプチェーン内のオブジェクトがそのプロパティの値を持っている場合、その値が返されます。そのようなプロパティが見つからない場合は JavaScript はそのオブジェクトにはそのプロパティがないと報告します。このようにして、<code>mark</code> オブジェクトには次のようなプロパティと値が入ることになります。</p> +<pre class="eval">mark.name = ""; +mark.dept = "general"; +mark.projects = []; +</pre> +<p><code>mark</code> オブジェクトは <code>mark.__proto__</code> の原型的なオブジェクトから name および dept プロパティの値を継承します。WorkerBee コンストラクタによって projects プロパティにローカルの値が代入されます。このことでプロパティとその値を継承することができます。このプロセスの細かいところは <a href="/ja/Core_JavaScript_1.5_Guide/Property_Inheritance_Revisited" title="ja/Core_JavaScript_1.5_Guide/Property_Inheritance_Revisited">プロパティの継承、再び</a> にて議論します。</p> +<p>これらのコンストラクタにインスタンス固有の値を渡せないため、この情報は汎用的になります。プロパティの値は WorkerBee によって作成されるすべての新しいオブジェクトに共有される、デフォルトの値になります。もちろん、これらのどのプロパティのでもその値を変えることができます。そのためには次のようにして <code>mark</code> に固有の情報を与えます。</p> +<pre class="eval">mark.name = "Doe, Mark"; +mark.dept = "admin"; +mark.projects = ["navigator"]; +</pre> +<div class="noinclude"> + <p>{{ PreviousNext("Core JavaScript 1.5 Guide:The Employee Example:Object Properties", "Core JavaScript 1.5 Guide:The Employee Example:Object Properties:Adding Properties") }}</p> +</div> diff --git a/files/ja/web/javascript/guide/using_promises/index.html b/files/ja/web/javascript/guide/using_promises/index.html new file mode 100644 index 0000000000..df6cd820bc --- /dev/null +++ b/files/ja/web/javascript/guide/using_promises/index.html @@ -0,0 +1,358 @@ +--- +title: Promiseを使う +slug: Web/JavaScript/Guide/Using_promises +tags: + - Guide + - Intermediate + - JavaScript + - Promise + - Promises + - asynchronous + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Using_promises +--- +<div>{{jsSidebar("JavaScript Guide")}}</div> + +<p class="summary">{{jsxref("Promise")}} は非同期処理の最終的な完了もしくは失敗を表すオブジェクトです。多くの人々は既存の用意された Promise を使うことになるため、このガイドでは、Promise の作成方法の前に、関数が返す Promise の使い方から説明します。</p> + +<p>本質的に、Promise はコールバックを関数に渡すかわりに、関数が返したオブジェクトに対してコールバックを登録するようにする、というものです。</p> + +<p>例えば <code>createAudioFileAsync()</code> という非同期に音声ファイルを生成する関数を考えましょう。この関数はコンフィグオブジェクトと 2 つのコールバック関数を受け取り、片方のコールバックは音声ファイルが無事作成されたときに呼び出され、もう一つはエラーが発生したときに呼び出されます。</p> + +<p>以下のコードは <code>createAudioFileAsync()</code> を使用したものです。</p> + +<pre class="brush: js notranslate">function successCallback(result) { + console.log("Audio file ready at URL: " + result); +} + +function failureCallback(error) { + console.log("Error generating audio file: " + error); +} + +createAudioFileAsync(audioSettings, successCallback, failureCallback);</pre> + +<p>最近では関数は Promise を返し、代わりにその Promise にコールバックを登録することができます。</p> + +<p>もし <code>createAudioFileAsync()</code> が Promise を返すように書き換えられたとすれば、以下のようにシンプルに使用することができます。</p> + +<pre class="brush: js notranslate">createAudioFileAsync(audioSettings).then(successCallback, failureCallback);</pre> + +<p>これは以下のコードの短縮形です。</p> + +<pre class="brush: js notranslate">const promise = createAudioFileAsync(audioSettings); +promise.then(successCallback, failureCallback);</pre> + +<p>これを<em>非同期関数呼び出し(asynchronnous function call)</em>と呼びます。この記述方法にはいくつか利点があるので、順に説明します。</p> + +<h2 id="Guarantees" name="Guarantees">保証</h2> + +<p>旧来のコールバック渡しとは異なり、Promise では以下が保証されています。</p> + +<ul> + <li>現在の JavaScript イベントループの<a href="/ja/docs/Web/JavaScript/EventLoop#Run-to-completion">実行完了</a>より前には、コールバックが決して呼び出されない。</li> + <li>非同期処理が完了もしくは失敗した後に <code><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">then()</a></code> により登録されたコールバックでも、上記のように呼び出される。</li> + <li><code><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">then()</a></code> を何回も呼び出して複数のコールバックを追加してもよく、それぞれのコールバックは追加順に独立して実行される。</li> +</ul> + +<p>とはいえ、最もすぐわかる Promise の利点は <strong>Promise チェーン</strong>でしょう。</p> + +<h2 id="Chaining" name="Chaining">Promise チェーン</h2> + +<p>一般的なニーズとしては、複数の非同期処理を順番に実行し、前の処理が完了してからその結果を次の処理で使うというものがあります。これは <strong>Promise チェーン</strong>を作成することで行えます。</p> + +<p>さあ魔法の時間です。<code>then()</code> 関数は元の Promise とは別の<strong>新しい Promise</strong> を返します。</p> + +<pre class="brush: js notranslate">const promise = doSomething(); +const promise2 = promise.then(successCallback, failureCallback); +</pre> + +<p>もしくは、以下のように書いても構いません。</p> + +<pre class="brush: js notranslate">const promise2 = doSomething().then(successCallback, failureCallback); +</pre> + +<p>2 つ目の Promise は <code>doSomething()</code> の完了を表すだけではなく、渡した <code>successCallback</code> もしくは <code>failureCallback</code> の完了も表し、これらのコールバックは Promise を返すまた別の非同期関数であっても構いません。その場合、<code>promise2</code> に追加されたコールバックはいずれも Promise のキューにおいて、<code>successCallback</code> または <code>failureCallback</code> が返す Promise の後ろに追加されます。</p> + +<p>基本的に、それぞれの Promise はチェーン(連鎖)上の各非同期処理の完了を表します。</p> + +<p>昔は、複数の非同期処理を順番に実行するには、従来のコールバック地獄を作ることになりました。</p> + +<pre class="brush: js notranslate">doSomething(function(result) { + doSomethingElse(result, function(newResult) { + doThirdThing(newResult, function(finalResult) { + console.log('Got the final result: ' + finalResult); + }, failureCallback); + }, failureCallback); +}, failureCallback); +</pre> + +<p>モダンな関数を使えば、その代わりに戻り値の Promise にコールバックを付加して Promise チェーンとして記述できます。</p> + +<pre class="brush: js notranslate">doSomething() +.then(function(result) { + return doSomethingElse(result); +}) +.then(function(newResult) { + return doThirdThing(newResult); +}) +.then(function(finalResult) { + console.log('Got the final result: ' + finalResult); +}) +.catch(failureCallback); +</pre> + +<p> <code>then</code> 関数の引数はオプション(必須ではない)です。また、<code>catch(failureCallback)</code> は <code>then(null, failureCallback)</code> の短縮形です。記述には<a href="/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions">アロー関数</a>を使っても構いません。</p> + +<pre class="brush: js notranslate">doSomething() +.then(result => doSomethingElse(result)) +.then(newResult => doThirdThing(newResult)) +.then(finalResult => { + console.log(`Got the final result: ${finalResult}`); +}) +.catch(failureCallback); +</pre> + +<p><strong>重要:</strong> コールバック関数から処理結果を返すのを忘れないでください。さもないと後続のコールバック関数からその処理結果を利用することができなくなります (アロー関数を使った <code>() => x</code> は <code>() => { return x; }</code> の短縮形です)。</p> + +<h3 id="Chaining_after_a_catch" name="Chaining_after_a_catch">catch後のチェーン</h3> + +<p>失敗、つまり <code>catch</code> の後にチェーンするのも可能で、これはチェーン内の動作が失敗した後でも新しい動作を行うのに便利です。次の例を読んでください:</p> + +<pre class="brush: js notranslate">new Promise((resolve, reject) => { + console.log('Initial'); + + resolve(); +}) +.then(() => { + throw new Error('Something failed'); + + console.log('Do this'); +}) +.catch(() => { + console.log('Do that'); +}) +.then(() => { + console.log('Do this whatever happened before'); +});</pre> + +<p>これは下記のテキストを出力します:</p> + +<pre class="notranslate">Initial +Do that +Do this whatever happened before</pre> + +<p><strong>注意:</strong><q>Do this</q> のテキストは <q>Something failed</q> エラーが reject を引き起こしたため出力されないことに注意してください。</p> + +<h2 id="Error_propagation" name="Error_propagation">エラーの伝播</h2> + +<p>以前のコールバック地獄形式の記述方法では <code>failureCallback</code> を 3 回書く必要がありましたが、Promise チェーンでは <code>failureCallback</code> は 1 回で済みます。</p> + +<pre class="brush: js notranslate">doSomething() +.then(result => doSomethingElse(result)) +.then(newResult => doThirdThing(newResult)) +.then(finalResult => console.log(`Got the final result: ${finalResult}`)) +.catch(failureCallback); +</pre> + +<p>例外が発生すると、ブラウザーはチェーンをたどって <code>.catch()</code> ハンドラーか <code>onRejected</code> を探します。この振る舞いは同期的なコードの動作と非常によく類似しています。</p> + +<pre class="brush: js notranslate">try { + const result = syncDoSomething(); + const newResult = syncDoSomethingElse(result); + const finalResult = syncDoThirdThing(newResult); + console.log(`Got the final result: ${finalResult}`); +} catch(error) { + failureCallback(error); +} +</pre> + +<p>ECMAScript 2017 のシンタックスシュガー <a href="/ja/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a> を使えば、完全にそっくりのコードになります。</p> + +<pre class="brush: js notranslate">async function foo() { + try { + const result = await doSomething(); + const newResult = await doSomethingElse(result); + const finalResult = await doThirdThing(newResult); + console.log(`Got the final result: ${finalResult}`); + } catch(error) { + failureCallback(error); + } +} +</pre> + +<p>async/await は Promise の上に成り立っています。例えば上記の <code>doSomething()</code> はこれまでと同じ(Promise を返す)関数です。この書き方の詳細については<a href="https://developers.google.com/web/fundamentals/getting-started/primers/async-functions">こちら</a>をご覧ください。</p> + +<p>Promise は例外やプログラミングエラーを含むすべてのエラーをとらえることで、コールバック地獄の根本的な問題を解決します。これは非同期処理を合成するのに不可欠です。</p> + +<h2 id="Promise_rejection_events" name="Promise_rejection_events">Promise の失敗イベント</h2> + +<p>Promise が失敗するたびに、グローバルスコープ(通常 {{domxref("window")}} オブジェクトか、Web Worker 内ならば <a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/Worker" title="Worker インターフェイス of the Web Workers API represents a background task that can be created via script, which can send messages back to its creator."><code>Worker</code></a> か Worker ベースのインターフェイスをもつオブジェクト)に以下の 2 つのイベントのどちらかが送られます:</p> + +<dl> + <dt><a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/Window/rejectionhandled_event" title="The rejectionhandled event is sent to the script's global scope (usually window but also Worker) whenever a JavaScript Promise is rejected but after the promise rejection has been handled."><code>rejectionhandled</code></a></dt> + <dd>Promise が失敗したとき、それが <code>reject</code> 関数などによって処理されたあとに送られる。</dd> + <dt><a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/Window/unhandledrejection_event" title="The unhandledrejection event is sent to the global scope of a script when a JavaScript Promise that has no rejection handler is rejected; typically, this is the window, but may also be a Worker."><code>unhandledrejection</code></a></dt> + <dd>Promise が失敗して、ハンドラーが存在しないときに送られる。</dd> +</dl> + +<p>いずれの場合でも、イベントオブジェクト( <a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/PromiseRejectionEvent" title="PromiseRejectionEvent インターフェイス represents events which are sent to the global script context when JavaScript Promises are rejected."><code>PromiseRejectionEvent</code></a> 型)は失敗した Promise を表す <a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/PromiseRejectionEvent/promise" title="The PromiseRejectionEvent interface's promise read-only property indicates the JavaScript Promise which was rejected. You can examine the event's PromiseRejectionEvent.reason property to learn why the promise was rejected."><code>promise</code></a> プロパティと、その Promise が失敗した理由を表す <a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/PromiseRejectionEvent/reason" title="The read-only PromiseRejection property reason read-only property is any JavaScript value or Object which provides the reason passed into Promise.reject(). This in theory provides information about why the promise was rejected."><code>reason</code></a> プロパティを持ちます。</p> + +<p>これらのイベントを使えば、Promise のエラーハンドラーのフォールバックを指定することができ、また Promise を管理する際の問題をデバッグするのにも役立ちます。これらのイベントのハンドラーはコンテキストごとにグローバルであり、どこから発生したかに関わらず、すべてのエラーは同じイベントハンドラーによって処理されます。</p> + +<p>特に便利なケースとして、{{Glossary("Node.js")}} 用のコードを書いているときにプロジェクト内のモジュールで Promise が失敗しハンドルされないことがよくあります。これらは Node.js の実行環境によりコンソールに出力されます。これらの失敗を分析したりハンドラーを設定したいとき、あるいは単にコンソールがこれらで埋め尽くされないようにしたいとき、以下のように <a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/Window/unhandledrejection_event" title="The unhandledrejection event is sent to the global scope of a script when a JavaScript Promise that has no rejection handler is rejected; typically, this is the window, but may also be a Worker."><code>unhandledrejection</code></a> イベントのハンドラーを追加することができます。</p> + +<pre class="brush: js notranslate">window.addEventListener("unhandledrejection", event => { + /* ここで該当の Promise を event.promise で、失敗の理由を + event.reason で取得して調べることができます */ + + event.preventDefault(); +}, false);</pre> + +<p>イベントの <a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/Event/preventDefault" title="The Event interface's preventDefault() method tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be."><code>preventDefault()</code></a> メソッドを呼び出すことによって、失敗した Promise がハンドルされないときの JavaScript の実行環境のデフォルトの動作を防ぐことができます。特に Node.js がそうですが、通常はデフォルトの動作ではエラーがコンソールに出力されます。</p> + +<p>当然ながら理想的には、これらのイベントを捨てる前に失敗した Promise を調べて、いずれもコードのバグによるものではないことを確かめるべきです。</p> + +<h2 id="Creating_a_Promise_around_an_old_callback_API" name="Creating_a_Promise_around_an_old_callback_API">古いコールバック API をラップする Promise の作成</h2> + +<p>{{jsxref("Promise")}} はコンストラクタを使って 1 から作ることもできます。これは古い API をラップする場合にのみ必要となるはずです。</p> + +<p>理想的には、すべての非同期関数は Promise を返すはずですが、残念ながら API の中にはいまだに古いやり方で成功/失敗用のコールバックを渡しているものがあります。典型的な例としては <a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/WindowTimers/setTimeout" title="The documentation about this has not yet been written; please consider contributing!"><code>setTimeout()</code></a> 関数があります。</p> + +<pre class="brush: js notranslate">setTimeout(() => saySomething("10 seconds passed"), 10*1000); +</pre> + +<p>古い形式のコールバックと Promise の混在は問題を引き起こします。というのは、<code>saySomething()</code> が失敗したりプログラミングエラーを含んでいた場合にそのエラーをとらえられないからです。<code>setTimeout</code> にその責任があります。</p> + +<p>幸いにも <code>setTimeout</code> を Promise の中にラップすることができます。ベストプラクティスは、問題のある関数を可能な限り低いレベルでラップした上で、二度と直接呼ばないようにするというものです。</p> + +<pre class="brush: js notranslate">const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); + +wait(10*1000).then(() => saySomething("10 seconds")).catch(failureCallback); +</pre> + +<p>基本的に、Promise のコンストラクタには、手動で Promise を resolve もしくは reject できるようにする実行関数を渡します。<code>setTimeout()</code> は失敗することはないので、reject は省略しました。</p> + +<h2 id="Composition" name="Composition">合成 (Composition)</h2> + +<p>{{jsxref("Promise.resolve()")}} と {{jsxref("Promise.reject()")}} はそれぞれ既に resolve もしくは reject された Promise を手動で作成するショートカットで、たまに役立つことがあります。</p> + +<p>{{jsxref("Promise.all()")}} と {{jsxref("Promise.race()")}} は同時並行で実行中の非同期処理を合成するためのツールです。</p> + +<p>以下のように複数の処理を並行に開始し、すべてが終了するのを待つことができます。</p> + +<pre class="brush: js notranslate">Promise.all([func1(), func2(), func3()]) +.then(([result1, result2, result3]) => { /* result1, result2, result3 が使える */ });</pre> + +<p>以下のように工夫すれば、逐次実行をする直列的な合成も記述することができます。</p> + +<pre class="brush: js notranslate">[func1, func2].reduce((p, f) => p.then(f), Promise.resolve()) +.then(result3 => { /* result3 が使える */ });</pre> + +<p>基本的に、これは非同期関数の配列を <code><span class="pun">Promise.resolve().then(</span><span class="pln">func1).then(</span><span class="pln">func2</span><span class="pun">).then(func3);</span></code><span class="pun"> と同等の Promise チェーンへと reduce しています。</span></p> + +<p>このような処理は以下のように、関数型プログラミングでよくある再利用可能な合成関数にすることがすることができます。</p> + +<pre class="brush: js notranslate">const applyAsync = (acc,val) => acc.then(val); +const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));</pre> + +<p><code>composeAsync</code> 関数は任意の個数の関数を引数として受け取って、1本のパイプラインとして合成された関数を返します。この関数に渡された初期値は合成された関数を通過していきます。</p> + +<pre class="brush: js notranslate">const transformData = composeAsync(func1, func2, func3); +const result3 = transformData(data);</pre> + +<p>ECMAScript 2017 では直列的な合成は async/await でもっと単純に書くことができます。</p> + +<pre class="brush: js notranslate">let result; +for (const f of [func1, func2, func3]) { + result = await f(result); +} +/* 最終的な結果(result3)が使える */</pre> + +<h2 id="Timing" name="Timing">タイミング</h2> + +<p>想定外の事態とならないよう、たとえすでに resolve された Promise であっても、<code><a href="https://wiki.developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">then()</a></code> に渡される関数が同期的に呼ばれることはありません。</p> + +<pre class="brush: js notranslate">Promise.resolve().then(() => console.log(2)); +console.log(1); // 1, 2 +</pre> + +<p>渡された関数は、すぐに実行されるのではなくマイクロタスクのキューに入れられます。現在のイベントループの終わりにこのキューは空になったときに、この関数が実行されます(つまりかなり早い段階です)。</p> + +<pre class="brush: js notranslate">const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); + +wait().then(() => console.log(4)); +Promise.resolve().then(() => console.log(2)).then(() => console.log(3)); +console.log(1); // 1, 2, 3, 4</pre> + +<h2 id="Nesting" name="Nesting">ネスト</h2> + +<p>単純な Promise チェーンならば、ネストは不用意な合成の結果生まれるものなので、ネストせずに平らにしておくのがベストです。<a href="#Common_mistakes">よくある間違い</a>を参照してください。</p> + +<p>ネストとは <code>catch</code> ステートメントのスコープを制限するための制御構造です。正確には、ネストされた <code>catch</code> はそのスコープ内の失敗しかキャッチせず、Promise チェーン上でスコープ外のエラーには反応しません。正しく使えばより正確にエラーからの回復ができるようになります。</p> + +<pre class="brush: js notranslate">doSomethingCritical() +.then(result => doSomethingOptional(result) + .then(optionalResult => doSomethingExtraNice(optionalResult)) + .catch(e => {})) // オプションの処理が失敗すれば無視して進める +.then(() => moreCriticalStuff()) +.catch(e => console.log("Critical failure: " + e.message));</pre> + +<p>インデントではなく外側の括弧 <code>()</code> によってオプションの処理がネストされていることに注意してください。</p> + +<p>内側の <code>catch</code> ステートメントは <code>doSomethingOptional()</code> と <code>doSomethingExtraNice()</code> からの失敗だけをキャッチし、キャッチしたあと <code>moreCriticalStuff()</code> へと処理が続きます。重要なのは、もし <code>doSomethingCritical()</code> が失敗したらそのエラーは最後の <code>catch</code> によってだけキャッチされるということです。</p> + +<h2 id="Common_mistakes" name="Common_mistakes">よくある間違い</h2> + +<p>Promise チェーンを合成するときは以下のようなよくある間違いに気をつける必要があります。以下の例にいくつかの間違いが含まれています。</p> + +<pre class="brush: js example-bad notranslate">// 悪い例。間違いを 3 つ見つけてください。 + +doSomething().then(function(result) { + doSomethingElse(result) // 内側のチェーンから Promise を返していない + 不必要なネスト + .then(newResult => doThirdThing(newResult)); +}).then(() => doFourthThing()); +// チェーンの最後を catch で終わらせていない +</pre> + +<p>最初の間違いは適切にチェーンを構成できていないことです。これは、新しい Promise を作成したがそれを返すのを忘れているときに起きます。結果としてチェーンは壊れ、2 つのチェーンが独立に実行されることになります。これはつまり <code>doFourthThing()</code> は <code>doSomethingElse()</code> や <code>doThirdThing()</code> の終了を待たないことになり、おそらく意図せず並行して実行されることになります。別々のチェーンでは別々のエラーハンドリングが行われるため、キャッチされないエラーが発生することになります。</p> + +<p>2 つ目の間違いは不必要にネストしていることであり、1 つめの間違いを可能にしているものでもあります。ネストするということは内側のエラーハンドラーが制限されるということであり、もしこれが意図していないものであれば、エラーがキャッチされないということが起こりえます。これの変化形で <a href="https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it">Promise コンストラクターアンチパターン</a>というものがあり、ネストに加えて、Promise を既に使用しているコードを不必要な Promise コンストラクターでラップするというものです。</p> + +<p>3 つ目の間違いはチェーンを <code>catch</code> で終わらせていないことです。ほとんどのブラウザーではそのようなチェーンは Promise の失敗がキャッチされないことになります。</p> + +<p>よい経験則としては、Promise チェーンは常に <code>return</code> するか <code>catch</code> で終わらせ、新しい Promise を得るたびにすぐに <code>return</code> してチェーンを平らにすることです。</p> + +<pre class="brush: js example-good notranslate">doSomething() +.then(function(result) { + return doSomethingElse(result); +}) +.then(newResult => doThirdThing(newResult)) +.then(() => doFourthThing()) +.catch(error => console.log(error)); +</pre> + +<p><code>() => x</code> は <code>() => { return x; }</code> の短縮形であることに注意してください。</p> + +<p>これで適切なエラーハンドリングがされた 1本のチェーンができました。</p> + +<p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a> を使えば、すべてではないにしてもほとんどの問題は解決しますが、このシンタックスで最もよくある間違いが <code><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function">await</a></code> キーワードを忘れることであるという欠点があります。</p> + +<h2 id="When_promises_and_tasks_collide" name="When_promises_and_tasks_collide">Promises とタスクが衝突するとき</h2> + +<p>(イベントとコールバックのような) Promise とタスクが予知できない順序で発火するような状況に陥る場合、Promise が条件付きで作成されて Promise の状態をチェックしたり帳尻合わせしたりするマイクロタスクを利用できることがあります。</p> + +<p>マイクロタスクでこの問題を解決できると考えたなら、<a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/HTML_DOM_API/Microtask_guide">microtask guide</a> を見て、関数をマイクロタスクでキューに入れる <a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask" title="The queueMicrotask() method, which is exposed on the Window or Worker interface, queues a microtask to be executed at a safe time prior to control returning to the browser's event loop."><code>queueMicrotask()</code></a> の使い方を学んでください。</p> + +<h2 id="See_also" name="See_also">関連項目</h2> + +<ul> + <li>{{jsxref("Promise.then()")}}</li> + <li><a href="https://wiki.developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a></li> + <li><a href="http://promisesaplus.com/">Promises/A+ specification</a></li> + <li><a href="https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53">Venkatraman.R - JS Promise (Part 1, Basics)</a></li> + <li><a href="https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski">Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)</a></li> + <li><a href="https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction">Venkatraman.R - Tools for Promises Unit Testing</a></li> + <li><a href="http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html">Nolan Lawson: We have a problem with promises — Common mistakes with promises</a></li> +</ul> + +<p>{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</p> diff --git a/files/ja/web/javascript/guide/using_the_arguments_object/index.html b/files/ja/web/javascript/guide/using_the_arguments_object/index.html new file mode 100644 index 0000000000..10c2d9e3ff --- /dev/null +++ b/files/ja/web/javascript/guide/using_the_arguments_object/index.html @@ -0,0 +1,36 @@ +--- +title: arguments オブジェクトの使用 +slug: Web/JavaScript/Guide/Using_the_arguments_object +--- +<div class="onlyinclude"> + <h3 id="arguments_オブジェクトの使用"><code>arguments</code> オブジェクトの使用</h3> + <p>関数の引数は配列のようなオブジェクトで管理されます。関数内では、次のようにして渡された引数を指すことができます。</p> + <pre class="eval">arguments[i] +</pre> + <p>ここで <code>i</code> は引数の順序を表す数を指します。これは 0 から始まります。関数に渡された第 1 引数は <code>arguments{{ mediawiki.external(0) }}</code> となります。引数のトータルの数は <code>arguments.length</code> で示されます。</p> + <p><code>arguments</code> オブジェクトを使用すると、宣言時の仮引数の数よりも多くの引数を使って関数を呼び出すことができます。これはその関数に渡す引数の数が前もってわかっていない場合に役立ちます。<code>arguments</code>.length を使用することで実際にその関数に渡された引数の数を特定することができます。また、<code>arguments</code> オブジェクトを使用することで各引数を扱うことができます。</p> + <p>例えば、複数の文字列を連結する関数を考えます。この関数の仮引数は、連結するアイテムを区切るのに用いる文字列のみです。この関数は次のように定義されています。</p> + <pre class="eval">function myConcat(separator) { + var result = ""; // リストを初期化する + // 引数について繰り返し + for (var i = 1; i < arguments.length; i++) { + result += arguments[i] + separator; + } + return result; +} +</pre> + <p>この関数に引数をいくつも渡すことができます。そして各引数を文字列のリストに連結します。</p> + <pre class="eval">// "red, orange, blue, " を返す +myConcat(", ", "red", "orange", "blue"); + +// "elephant; giraffe; lion; cheetah; " を返す +myConcat("; ", "elephant", "giraffe", "lion", "cheetah"); + +// "sage. basil. oregano. pepper. parsley. " を返す +myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley"); +</pre> + <p>さらなる情報については、コア JavaScript リファレンスの <a href="/ja/Core_JavaScript_1.5_Reference/Objects/Function" title="ja/Core_JavaScript_1.5_Reference/Objects/Function">Function オブジェクト</a> をご覧ください。</p> + <p><strong>JavaScript 1.3 以前のバージョン</strong><br> + arguments オブジェクトは <code>Function</code> オブジェクトのプロパティであり、次のように関数の名前を前に付けることができます。</p> + functionName.arguments{{ mediawiki.external('i') }}</div> +<p>{{ PreviousNext("JavaScript/Guide/Calling_Functions", "JavaScript/Guide/Predefined_Functions") }}</p> diff --git a/files/ja/web/javascript/guide/variables/index.html b/files/ja/web/javascript/guide/variables/index.html new file mode 100644 index 0000000000..cebaecc949 --- /dev/null +++ b/files/ja/web/javascript/guide/variables/index.html @@ -0,0 +1,62 @@ +--- +title: 変数 +slug: Web/JavaScript/Guide/Variables +--- +<p>{{ 英語版章題("Variables") }}</p> +<h3 id=".E5.A4.89.E6.95.B0" name=".E5.A4.89.E6.95.B0">変数</h3> +<p>アプリケーションで値を識別する名前として変数を使用します。変数の名前はあるルールに従って付けなくてはなりません。変数の名前は<em>識別子</em>とも呼ばれます。</p> +<p>JavaScript の識別子は必ずアルファベットかアンダースコア (_) かドル記号 ($) から始まらなくてはなりません。続く文字は数字 (0-9) も使えます。JavaScript は大文字・小文字を区別するため、使えるアルファベットは "A" から "Z"(大文字)と "a" から "z"(小文字)です。</p> +<p>JavaScript 1.5 からは å や ü といった ISO 8859-1 や Unicode のアルファベットも識別子に使えます。<a href="/ja/Core_JavaScript_1.5_Guide/Unicode#Unicode_Escape_Sequences" title="ja/Core_JavaScript_1.5_Guide/Unicode#Unicode_Escape_Sequences">Unicode エスケープシーケンス</a> のページに列挙されている \uXXXX 形式の Unicode エスケープシーケンスも識別子に使用できます。</p> +<p><code>Number_hits</code> や <code>temp99</code> や <code>_name</code> が使用できる名前の例です。</p> +<p>{{ 英語版章題("Declaring Variables") }}</p> +<h4 id=".E5.A4.89.E6.95.B0.E3.81.AE.E5.AE.A3.E8.A8.80" name=".E5.A4.89.E6.95.B0.E3.81.AE.E5.AE.A3.E8.A8.80">変数の宣言</h4> +<p>2 つの方法で変数を宣言できます。</p> +<ul> + <li><a href="/ja/Core_JavaScript_1.5_Reference/Statements/var" title="ja/Core_JavaScript_1.5_Reference/Statements/var">var</a> というキーワードを使う。例えば、<code>var x = 42</code>。この構文は <a href="#.E5.A4.89.E6.95.B0.E3.81.AE.E3.82.B9.E3.82.B3.E3.83.BC.E3.83.97">ローカルおよびグローバル</a> 変数どちらの宣言にも使用可能です。</li> + <li>単に値を代入する。例えば、<code>x = 42</code>。これはいつでも <a href="#.E3.82.B0.E3.83.AD.E3.83.BC.E3.83.90.E3.83.AB.E5.A4.89.E6.95.B0">グローバル変数</a> を宣言できますが、{{ 原語併記("厳格な JavaScript 警告", "strict JavaScript warning") }}が発生します。この方法は使用すべきではありません。</li> +</ul> +<p>{{ 英語版章題("Evaluating Variables") }}</p> +<h4 id=".E5.A4.89.E6.95.B0.E3.81.AE.E8.A9.95.E4.BE.A1" name=".E5.A4.89.E6.95.B0.E3.81.AE.E8.A9.95.E4.BE.A1">変数の評価</h4> +<p><code>var</code> 文を使用し、初期化せずに宣言された変数は <a href="/ja/Core_JavaScript_1.5_Reference/Global_Properties/undefined" title="ja/Core_JavaScript_1.5_Reference/Global_Properties/undefined">undefined</a> の値をとります。</p> +<p>未宣言の変数にアクセスしようとすると、ReferenceError 例外が投げられます。</p> +<pre class="eval">var a; +print("a の値は " + a); // "a の値は undefined" を出力 +print("b の値は " + b); // ReferenceError 例外を投げる +</pre> +<p><code>undefined</code> を使うと変数に値が入っているかどうかを確かめられます。以下のコードでは、変数 <code>input</code> には値が代入されておらず、<code><a href="/ja/Core_JavaScript_1.5_Reference/Statements/if...else" title="ja/Core_JavaScript_1.5_Reference/Statements/if...else">if</a></code> 文での評価結果は <code>true</code> です。</p> +<pre class="eval">var input; +if(input === undefined){ + doThis(); +} else { + doThat(); +} +</pre> +<p><span class="comment">Not sure how the following is related to "Variables" section</span> <code>undefined</code> は真偽値コンテキストで使用されると <code>false</code> として振る舞います。例えば以下のコードでは、<code>myArray</code> の要素が未定義であるために関数 <code>myFunction</code> が実行されます。</p> +<pre class="eval">var myArray = new Array(); +if (!myArray[0]) myFunction(); +</pre> +<p>null 変数を評価すると、数値コンテキストにおいては null 値は 0 として振る舞います。また、真偽値コンテキストでは false として振る舞います。</p> +<pre class="eval">var n = null; +print(n * 32); // prints 0 +</pre> +<p>{{ 英語版章題("Variable Scope") }}</p> +<h4 id=".E5.A4.89.E6.95.B0.E3.81.AE.E3.82.B9.E3.82.B3.E3.83.BC.E3.83.97" name=".E5.A4.89.E6.95.B0.E3.81.AE.E3.82.B9.E3.82.B3.E3.83.BC.E3.83.97">変数のスコープ</h4> +<p>変数を関数の外側で宣言すると、その変数はその文書のどのコードからも使用できるようになるため、<em>グローバル</em>(大域)変数と呼ばれます。変数を関数の内部で宣言すると、その変数はその関数の中でしか使用できないため、<em>ローカル</em>(局所)変数と呼ばれます。</p> +<p>JavaScript には <a href="/ja/Core_JavaScript_1.5_Guide/Block_Statement#.E3.83.96.E3.83.AD.E3.83.83.E3.82.AF.E6.96.87" title="ja/Core_JavaScript_1.5_Guide/Block_Statement#.E3.83.96.E3.83.AD.E3.83.83.E3.82.AF.E6.96.87">ブロック文</a> のスコープがありません。むしろ、そのブロックを内包しているコードに対して局所化されます。例えば以下のコードは <code>condition</code> が <code>false</code> のとき、例外を投げずに 0 が出力されます。</p> +<pre class="eval">if (condition) { + var x = 5; +} +print(x ? x : 0); +</pre> +<p>JavaScript の変数に関する独特なこととして、後に宣言される変数を例外を発生させることなく参照できるというのも挙げられます。</p> +<pre class="eval">print(x === undefined); // "true" を出力 +var x = 3; +</pre> +<p>{{ 英語版章題("Global Variables") }}</p> +<h4 id=".E3.82.B0.E3.83.AD.E3.83.BC.E3.83.90.E3.83.AB.E5.A4.89.E6.95.B0" name=".E3.82.B0.E3.83.AD.E3.83.BC.E3.83.90.E3.83.AB.E5.A4.89.E6.95.B0">グローバル変数</h4> +<p><span class="comment">need links to pages discussing scope chains and the global object</span> グローバル変数は実際には<em>グローバルオブジェクト</em>のプロパティです。ウェブページではグローバルオブジェクトは <a href="/ja/DOM/window" title="ja/DOM/window">window</a> です。そのため、<code>window.<em>variable</em></code> という構文を使うことでグローバル変数をセットしたり、グローバル変数にアクセスしたりすることができます。</p> +<p>したがって、あるウィンドウやフレームで宣言したグローバル変数に、そのウィンドウやフレームの名前を指定すれば別のウィンドウやフレームからアクセスできます。例えば、<code>phoneNumber</code> という変数を <code>FRAMESET</code> 文書内で宣言すると、子フレームから <code>parent.phoneNumber</code> としてこの変数を参照することができます。</p> +<p>{{ 英語版章題("See Also") }}</p> +<h4 id=".E9.96.A2.E9.80.A3.E9.A0.85.E7.9B.AE" name=".E9.96.A2.E9.80.A3.E9.A0.85.E7.9B.AE">関連項目</h4> +<p><a href="/ja/Sharp_variables_in_JavaScript" title="ja/Sharp_variables_in_JavaScript">JavaScript のシャープ変数</a></p> +<p>{{ PreviousNext("JavaScript/Guide/Values", "JavaScript/Guide/Constants") }}</p> diff --git a/files/ja/web/javascript/guide/working_with_objects/index.html b/files/ja/web/javascript/guide/working_with_objects/index.html new file mode 100644 index 0000000000..6200e1aa36 --- /dev/null +++ b/files/ja/web/javascript/guide/working_with_objects/index.html @@ -0,0 +1,496 @@ +--- +title: オブジェクトでの作業 +slug: Web/JavaScript/Guide/Working_with_Objects +tags: + - Beginner + - Document + - Guide + - JavaScript + - Object + - 'l10n:priority' + - オブジェクトの比較 + - コンストラクター +translation_of: Web/JavaScript/Guide/Working_with_Objects +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Keyed_collections", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}</div> + +<p class="summary">JavaScript は、シンプルなオブジェクトベースの枠組みを持つ言語として設計されています。JavaScript におけるオブジェクトはプロパティの集まりであり、プロパティは名前 (あるいは<em>キー</em>) と値との関連付けから成り立っています。プロパティの値を関数にすることもでき、これはいわゆるオブジェクトのメソッドとなります。ブラウザーにあらかじめ定義されているオブジェクトに加え、独自のオブジェクトを定義することもできます。この節ではオブジェクト、プロパティ、関数、メソッドの使い方と、独自のオブジェクトを作成する方法を説明します。</p> + +<h2 id="Objects_overview" name="Objects_overview">オブジェクトの概要</h2> + +<p>他の多くのプログラミング言語と同様、JavaScript におけるオブジェクトも、現実世界の「もの」 (すなわちオブジェクト) になぞらえることができます。JavaScript におけるオブジェクトの概念は、現実世界に実在する「もの」との対比で解釈できます。</p> + +<p>JavaScript において、オブジェクトはプロパティと型を持つ独立した存在です。カップを例に考えてみましょう。カップは様々なプロパティ (特性) をもったもの (オブジェクト) です。カップは、色や形状、重さや材質といったプロパティを持っています。同様に、JavaScript のオブジェクトもプロパティを持つことができ、プロパティによってそのオブジェクトの特徴を定義することができます。</p> + +<h2 id="Objects_and_properties" name="Objects_and_properties">オブジェクトとプロパティ</h2> + +<p>JavaScript のオブジェクトは、自身に関連付けられたプロパティを持ちます。オブジェクトのプロパティは、オブジェクトに関連付けられている変数と捉えることができます。オブジェクトのプロパティは、オブジェクトに属するものという点を除けば、基本的に通常の JavaScript 変数と同じようなものです。オブジェクトのプロパティは、オブジェクトの特性を定義します。オブジェクトのプロパティには、単純なドット表記でアクセスします。</p> + +<pre class="brush: js notranslate">objectName.propertyName +</pre> + +<p>すべての JavaScript の変数と同じく、オブジェクト名 (通常の変数にもなります) とプロパティ名では、大文字と小文字は厳密に区別されます。プロパティに値を代入することでプロパティを定義する事ができます。以下のようにして、<code>myCar</code> という名前のオブジェクトを作成し、<code>make</code>、<code>model</code>、<code>year</code> という名前のプロパティを付与することができます</p> + +<pre class="brush: js notranslate">var myCar = new Object(); +myCar.make = 'Ford'; +myCar.model = 'Mustang'; +myCar.year = 1969; +</pre> + +<p>上記の例は、<strong><a href="/ja/docs/Web/JavaScript/Guide/Working_with_Objects#Object_initializers">オブジェクト初期化子</a></strong>を使用して作成することもできます。オブジェクト初期化子は、中括弧 (<code>{}</code>) で囲まれたオブジェクトのプロパティ名と関連する値の 0 個以上のペアをカンマで区切ったリストです。</p> + +<pre class="brush: js notranslate">var myCar = { + make: 'Ford', + model: 'Mustang', + year: 1969 +}; +</pre> + +<p>オブジェクトに割り当てられていないプロパティは {{jsxref("undefined")}} です ({{jsxref("null")}} ではありません)。</p> + +<pre class="brush: js notranslate">myCar.color; // undefined</pre> + +<p>JavaScript オブジェクトのプロパティは、ブラケット (角括弧) 記述法でもアクセスすることができます (詳しくは<a href="/ja/docs/Web/JavaScript/Reference/Operators/Property_Accessors">プロパティのアクセサー</a>を参照してください)。個々のプロパティが文字列値と関連付けられてアクセスできるため、オブジェクトは<em>連想配列</em>と呼ばれることがあります。ですから例えば、<code>myCar</code> オブジェクトのプロパティに次のようにアクセスできます。</p> + +<pre class="brush: js notranslate">myCar['make'] = 'Ford'; +myCar['model'] = 'Mustang'; +myCar['year'] = 1969; +</pre> + +<p>オブジェクトプロパティの名前には、あらゆる有効な JavaScript 文字列 (空文字列を含む) か、文字列に変換できるものが使用できます。しかしながら、JavaScript 識別子として有効ではないプロパティ名 (例えば空白やダッシュを含んでいたり、数字で始まったりするプロパティ名) には、ブラケット (角括弧) 表記法でのみアクセスできます。この表記法はプロパティ名を動的に決める場合 (プロパティ名が実行時に決まる場合) に便利です。例を示します。</p> + +<pre class="brush: js notranslate">// カンマで区切られた 4 つの変数が作成され、 +// 1 つに割り当てられます。 +var myObj = new Object(), + str = 'myString', + rand = Math.random(), + obj = new Object(); + +myObj.type = 'ドット表記'; +myObj['date created'] = '空白入りの文字列'; +myObj[str] = '文字列の値'; +myObj[rand] = '乱数'; +myObj[obj] = 'オブジェクト'; +myObj[''] = '空文字列も可能'; + +console.log(myObj); +</pre> + +<p>なお、JavaScript のオブジェクトのプロパティ名 (キー) は文字列かシンボルしか扱えないので、各括弧表記の中のキーはすべて、シンボルを除いて文字列に変換されます (将来、<a href="https://github.com/tc39/proposal-class-fields">クラスフィールドの提案</a>が進行すると、プライベート名も追加される予定ですが、<code>[]</code> の形は使用できません)。例えば、上記のコードで <code>obj</code> キーが <code>myObj</code> に追加されるとき、JavaScript は <code>obj.toString()</code> メソッドを呼び出し、結果の文字列を新しいキーとして使用します。</p> + +<p>変数内の文字列値を使ってプロパティにアクセスすることもできます。</p> + +<pre class="brush: js notranslate">var propertyName = 'make'; +myCar[propertyName] = 'Ford'; + +propertyName = 'model'; +myCar[propertyName] = 'Mustang'; +</pre> + +<p>ブラケット表記法を用いて <code><a href="/ja/docs/Web/JavaScript/Reference/Statements/for...in">for...in</a></code> でオブジェクトの列挙可能なプロパティすべてを巡回することができます。どのように動作するかを説明するため、以下にオブジェクトとオブジェクト名を引数として渡すと、オブジェクトのプロパティを表示する関数を示します。</p> + +<pre class="brush: js notranslate">function showProps(obj, objName) { + var result = ''; + for (var i in obj) { + // obj.hasOwnProperty() はオブジェクトのプロトタイプチェーンからプロパティを絞り込むために使用しています + if (obj.hasOwnProperty(i)) { + result += objName + '.' + i + ' = ' + obj[i] + '\n'; + } + } + return result; +} +</pre> + +<p>そして、<code>showProps(myCar, "myCar")</code> のように関数を呼び出すと次の結果が返ります。</p> + +<pre class="brush: js notranslate">myCar.make = Ford +myCar.model = Mustang +myCar.year = 1969</pre> + +<h2 id="Enumerate_the_properties_of_an_object" name="Enumerate_the_properties_of_an_object">オブジェクトの全プロパティの列挙</h2> + +<p><a href="/ja/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_5_support_in_Mozilla" title="ja/docs/JavaScript/ECMAScript 5 support in Mozilla">ECMAScript 5</a> 以降では、オブジェクトのプロパティをリストアップ/トラバース (横断走査) する言語特有の方法が 3 つあります。</p> + +<ul> + <li><code><a href="/ja/docs/Web/JavaScript/Reference/Statements/for...in" title="ja/docs/JavaScript/Reference/Statements/for...in">for...in</a></code> ループ<br> + この方法は、オブジェクトとそのプロトタイプチェーンにある列挙可能なプロパティをすべて横断します</li> + <li>{{jsxref("Object.keys", "Object.keys(o)")}}<br> + このメソッドは、そのオブジェクト独自の (プロトタイプチェーンを除く) 列挙可能なすべてのプロパティ名 ("keys") を配列で返します</li> + <li>{{jsxref("Object.getOwnPropertyNames", "Object.getOwnPropertyNames(o)")}}<br> + このメソッドは、そのオブジェクト独自のすべてのプロパティ名を (列挙可能かどうかに関わらず) 配列で返します</li> +</ul> + +<p>ECMAScript 5 よりも前では、オブジェクトの全プロパティを列挙する言語特有の方法はありません。しかし、次の関数で実現できます。</p> + +<pre class="brush: js notranslate">function listAllProperties(o) { + var objectToInspect; + var result = []; + + for(objectToInspect = o; objectToInspect !== null; + objectToInspect = Object.getPrototypeOf(objectToInspect)) { + result = result.concat( + Object.getOwnPropertyNames(objectToInspect) + ); + } + + return result; +} +</pre> + +<p>これは「隠された」プロパティ (プロトタイプチェーンのより近いところに他の同名のプロパティがあるために、オブジェクトを通してアクセスすることができないプロトタイプチェーン上のプロパティ) を見つけるのに便利です。アクセス可能なプロパティを列挙するには、配列内の重複を削除するだけで簡単に実現できます。</p> + +<h2 id="Creating_new_objects" name="Creating_new_objects">新しいオブジェクトの作成</h2> + +<p>JavaScript には数多くの定義済みオブジェクトがあります。さらに、独自のオブジェクトを定義できます。オブジェクトは{{jsxref("Operators/Object_initializer","オブジェクト初期化子","","true")}}を使って作成することができます。他にも、まずコンストラクター関数を作り、その関数を <code>new</code> 演算子との組み合わせで呼び出すことでオブジェクトをインスタンス化することもできます。</p> + +<h3 id="Using_object_initializers" name="Using_object_initializers"><span id="Object_initializers">オブジェクト初期化子の使用</span></h3> + +<p>コンストラクター関数を使ったオブジェクトの作成のほかに、<a href="/ja/docs/Web/JavaScript/Reference/Operators/Object_initializer">オブジェクト初期化子</a>を使用してオブジェクトを作成することができます。オブジェクト初期化子を使うことを、オブジェクトをリテラル表記法で作ると表現することがあります。「オブジェクト初期化子」は、C++ で使われる用語と同じ意味です。</p> + +<p>オブジェクト初期化子を使ったオブジェクトの構文は次のようになります。</p> + +<pre class="brush: js notranslate">var obj = { property_1: value_1, // property_# は識別子だったり、 + 2: value_2, // 数値だったり、 + // ..., + 'property n': value_n }; // 文字列だったりします +</pre> + +<p><code>obj</code> は新しいオブジェクトの名前、<code>property_<var>i</var></code> は識別子 (名前、数値、または文字列リテラルのいずれか)、<code>value_<var>i</var></code> は式で、その値が <code>property_<var>i</var></code> に代入されます。<code>obj</code> と代入は任意です。もし他の場所でこのオブジェクトを参照する必要がないのなら、変数への代入は不要です。(なお、もしオブジェクトが文の書かれる場所に現れる場合は、リテラルがブロック文と混同されないように、オブジェクトリテラルを括弧で囲む必要がある場合があります。)</p> + +<p>オブジェクト初期化子は式であり、それぞれのオブジェクト初期化子は、それが現れる文が実行されるたびにオブジェクトを作成する結果になります。オブジェクト初期化子が同一であっても、作成されるオブジェクトは互いに等しいとはみなされません。オブジェクトは <code>new Object()</code> の呼び出しが行われたかのように作成されます。つまり、オブジェクトリテラル式から作成されるオブジェクトは <code>Object</code> のインスタンスです。</p> + +<p>次の文では、式 <code>cond</code> が true の場合にのみオブジェクトを作り、変数 <code>x</code> に代入します。</p> + +<pre class="brush: js notranslate">if (cond) var x = {greeting: 'hi there'}; +</pre> + +<p>次の例では 3 つのプロパティを持った <code>myHonda</code> を作ります。なお、<code>engine</code> プロパティもまた、プロパティを持つオブジェクトです。</p> + +<pre class="brush: js notranslate">var myHonda = {color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}; +</pre> + +<p>配列を作るためにオブジェクト初期化子を使うこともできます。<a href="/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Array_literals">配列リテラル</a>を参照してください。</p> + +<h3 id="Using_a_constructor_function" name="Using_a_constructor_function">コンストラクター関数の使用</h3> + +<p>別の方法として、次の 2 つの手順でオブジェクトを作ることができます。</p> + +<ol> + <li>コンストラクター関数を記述してオブジェクトの型を定義します。この時、便宜上の理由から慣習的に、1 文字目は大文字とします。</li> + <li><code>new</code> でオブジェクトのインスタンスを作成します。</li> +</ol> + +<p>オブジェクトの型を定義するには、名前、プロパティ、メソッドを指定するオブジェクト型用の関数を作ります。例えば、車についてのオブジェクト型を作りたいとしましょう。このオブジェクト型は <code>car</code> と呼ばれ、make、model、year のプロパティを持たせたいとします。これを行うには、以下のような関数を書きます。</p> + +<pre class="brush: js notranslate">function Car(make, model, year) { + this.make = make; + this.model = model; + this.year = year; +} +</pre> + +<p><code>this</code> を使うことで、関数に渡されたオブジェクトのプロパティに対し値を代入していることに注意してください。</p> + +<p>以下のようにして <code>mycar</code> と呼ばれるオブジェクトを作成できるようになりました。</p> + +<pre class="brush: js notranslate">var mycar = new Car('Eagle', 'Talon TSi', 1993); +</pre> + +<p>この文では <code>mycar</code> を作り、プロパティに指定した値を代入します。<code>mycar.make</code> の値は文字列 "Eagle" になり、<code>mycar.year</code> は整数 1993 になり、といった具合です。</p> + +<p><code>new</code> を使って <code>car</code> オブジェクトをいくつでも作れます。例えば、</p> + +<pre class="brush: js notranslate">var kenscar = new Car('Nissan', '300ZX', 1992); +var vpgscar = new Car('Mazda', 'Miata', 1990); +</pre> + +<p>オブジェクトは、別のオブジェクトをプロパティとして持つことができます。例えば、<code>person</code> という名前のオブジェクトを次のように定義しましょう。</p> + +<pre class="brush: js notranslate">function Person(name, age, sex) { + this.name = name; + this.age = age; + this.sex = sex; +} +</pre> + +<p>それから、2 個の新しい <code>person</code> オブジェクトを次のようにインスタンス化します。</p> + +<pre class="brush: js notranslate">var rand = new Person('Rand McKinnon', 33, 'M'); +var ken = new Person('Ken Jones', 39, 'M'); +</pre> + +<p>そして、<code>Car</code> の定義を <code>person</code> オブジェクトを取る <code>owner</code> プロパティを含むよう、以下のように書き換えることができます。</p> + +<pre class="brush: js notranslate">function Car(make, model, year, owner) { + this.make = make; + this.model = model; + this.year = year; + this.owner = owner; +} +</pre> + +<p>新しいオブジェクトをインスタンス化するには、以下のようにします。</p> + +<pre class="brush: js notranslate">var car1 = new Car('Eagle', 'Talon TSi', 1993, rand); +var car2 = new Car('Nissan', '300ZX', 1992, ken); +</pre> + +<p>新しいオブジェクトを作成する際、上の文ではリテラル文字列や整数値を渡す代わりに、オブジェクト <code>rand</code> と <code>ken</code> を引数 owner として渡していることに注意してください。そして、car2 の owner の名前を知りたければ、以下のプロパティでアクセスできます。</p> + +<pre class="brush: js notranslate">car2.owner.name +</pre> + +<p>なお、既に定義されたオブジェクトにはいつでもプロパティを追加することができます。例えば、以下の文は、</p> + +<pre class="brush: js notranslate">car1.color = 'black'; +</pre> + +<p>car1 にプロパティ <code>color</code> を追加し、そこに "black" という値を代入します。しかしながら、これは他のどのオブジェクトにも影響しません。同じ型のすべてのオブジェクトに新しいプロパティを追加するには、<code>car</code> オブジェクト型の定義にそのプロパティを追加する必要があります。</p> + +<h3 id="Using_the_Object.create_method" name="Using_the_Object.create_method">Object.create メソッドの使用</h3> + +<p>オブジェクトは {{jsxref("Object.create()")}} メソッドを使用して作成することもできます。このメソッドは、コンストラクター関数の定義なしに作りたいオブジェクトのプロトタイプを選べるため、とても便利です。</p> + +<pre class="brush: js notranslate">// Animal のプロパティとメソッドをカプセル化 +var Animal = { + type: 'Invertebrates', // プロパティの既定値、「無脊椎動物」 + displayType: function(){ // Animal の種類を表示するメソッド + console.log(this.type); + } +} + +// animal1 という新しい animal 型を作成 +var animal1 = Object.create(Animal); +animal1.displayType(); // 出力 : Invertebrates + +// Fishes という新しい animal 型を作成 +var fish = Object.create(Animal); +fish.type = 'Fishes'; +fish.displayType(); // 出力 : Fishes</pre> + +<h2 id="Inheritance" name="Inheritance">継承</h2> + +<p>JavaScript のすべてのオブジェクトは、1 つ以上の他のオブジェクトを継承しています。継承元になるオブジェクトはプロトタイプと呼ばれ、継承されたプロパティはコンストラクターの <code>prototype</code> オブジェクトにあります。詳細は<a href="/ja/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">継承とプロトタイプチェーン</a>を参照してください。</p> + +<h2 id="Indexing_object_properties" name="Indexing_object_properties">オブジェクトプロパティのインデックス付け</h2> + +<p>オブジェクトのプロパティは、プロパティ名または番号インデックスで参照することができます。名前によってプロパティを初期定義した場合、常に名前を使って参照する必要があり、インデックスによってプロパティを初期定義した場合、常にインデックスを使って参照する必要があります。</p> + +<p>この制限は、(以前に <code>Car</code> オブジェクト型に対して行ったように) コンストラクター関数でオブジェクトとプロパティを作るときや、個々のプロパティを明示的に定義した場合 (例えば <code>myCar.color = "red"</code>) に適用されます。初めにオブジェクトプロパティをインデックスで、たとえば <code>myCar[5] = "25 mpg"</code> のように定義した場合、以降そのプロパティは <code>myCar[5]</code> としてしか参照できません。</p> + +<p>このルールの例外は、<code>forms</code> 配列型オブジェクトのような HTML から反映された配列型オブジェクトです。この配列型オブジェクトにあるオブジェクトは、いつでもインデックス (文書中に現れる位置を基準としたもの) と名前 (定義されていれば) のどちらからも参照できます。例えば、文書内の 2 つ目の <code><FORM></code> タグが <code>NAME</code> 属性として "myForm" という値を持つとき、フォームは <code>document.forms[1]、</code><code>document.forms["myForm"]</code> 、<code>document.forms.myForm</code> のいずれかで参照できます。</p> + +<h2 id="Defining_properties_for_an_object_type" name="Defining_properties_for_an_object_type">オブジェクト型に対するプロパティの定義</h2> + +<p><code>prototype</code> プロパティを使用すると、定義済みのオブジェクト型に対してプロパティを追加することができます。このプロパティはオブジェクトの 1 つのインスタンスだけではなく、指定された型のすべてのオブジェクトで共有されます。次のコードはすべての <code>car</code> 型のオブジェクトに <code>color</code> プロパティを追加し、オブジェクト <code>car1</code> の <code>color</code> プロパティに値を代入します。</p> + +<pre class="brush: js notranslate">Car.prototype.color = null; +car1.color = 'black'; +</pre> + +<p>詳しくは、<a href="/ja/docs/JavaScript/Reference">JavaScript リファレンス</a>内にある、<code>Function</code> オブジェクトの <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype" title="ja/docs/JavaScript/Reference/Global Objects/Function/prototype"><code>prototype</code> プロパティ</a>を参照してください。</p> + +<h2 id="Defining_methods" name="Defining_methods">メソッドの定義</h2> + +<p>メソッドはオブジェクトに関連付けられた関数です。簡単に言えば、オブジェクトのプロパティである関数です。メソッドは通常の関数と同じ方法で定義されますが、オブジェクトのプロパティに代入される点が異なります。詳細は<a href="/ja/docs/Web/JavaScript/Reference/Functions/Method_definitions">メソッドの定義</a>を参照してください。例えば、</p> + +<pre class="brush: js notranslate">objectName.methodname = functionName; + +var myObj = { + myMethod: function(params) { + // ...処理を行う + } + + // これでも動作します + + myOtherMethod(params) { + // ...他の処理を行う + } +}; +</pre> + +<p>ここで <code>objectName</code> は既存のオブジェクトを、<code>methodname</code> はメソッドを割り当てたい名前を、<code>function_name</code> は関数の名前を指しています。</p> + +<p>そして次のようにオブジェクトに続けてメソッドを呼び出します。</p> + +<pre class="brush: js notranslate">object.methodname(params); +</pre> + +<p>オブジェクトのコンストラクター関数にメソッドの定義を含めることで、オブジェクト型に対してメソッドを定義することができます。以前に定義した <code>car</code> オブジェクトのプロパティを整形して表示する関数を定義するとします。例えば以下の通りです。</p> + +<pre class="brush: js notranslate">function displayCar() { + var result = '美しい ' + this.year + '年式 ' + this.make + + ' ' + this.model; + pretty_print(result); +} +</pre> + +<p><code>pretty_print</code> は水平線と文字列を表示する関数です。<code>this</code> を使ってメソッドが属するオブジェクトを参照していることに注意してください。</p> + +<p>次の文をオブジェクトの定義に追加すると、この関数を <code>car</code> のメソッドにできます。</p> + +<pre class="brush: js notranslate">this.displayCar = displayCar; +</pre> + +<p>そして、<code>car</code> の完全な定義は次のようになります。</p> + +<pre class="brush: js notranslate">function Car(make, model, year, owner) { + this.make = make; + this.model = model; + this.year = year; + this.owner = owner; + this.displayCar = displayCar; +} +</pre> + +<p>次のようにして、個々のオブジェクトに対して <code>displayCar</code> メソッドを呼び出せます。</p> + +<pre class="brush: js notranslate">car1.displayCar(); +car2.displayCar(); +</pre> + +<h2 id="Using_this_for_object_references" name="Using_this_for_object_references">オブジェクト参照のための <code>this</code> の使用</h2> + +<p>JavaScript には、メソッド内で現在のオブジェクトを参照するための <code><a href="/ja/docs/Web/JavaScript/Reference/Operators/this">this</a></code> +という特別なキーワードがあります。以下の例には、<code>Manager</code> と <code>Intern</code> という 2 つのオブジェクトがあり、それぞれが独自の <code>name</code>, <code>age</code>, <code>job</code> を持っています。関数 <code>sayHi()</code> の中に <code>this.name</code> があることに注目してください。2 つのオブジェクトに追加してそれらを呼び出すことで、<code>'Hello, My name is'</code> を返し、その特定のオブジェクトから <code>name</code> の値を追加しています。</p> + +<pre class="brush: js notranslate">const Manager = { + name: "John", + age: 27, + job: "Software Engineer" +} +const Intern = { + name: "Ben", + age: 21, + job: "Software Engineer Intern" +} + +function sayHi() { + console.log('Hello, my name is', this.name) +} + +// 両方のオブジェクトに sayHi 関数を追加 +Manager.sayHi = sayHi; +Intern.sayHi = sayHi; + +Manager.sayHi() // Hello, my name is John' +Intern.sayHi() // Hello, my name is Ben' +</pre> + +<p><code>this</code> は自身が入っているオブジェクトを参照します。上記の例に <code>howOldAmI()</code> という新しい関数を作って、その人の年齢を示す文をログに出力できます。</p> + +<pre class="brush: js notranslate">function howOldAmI (){ + console.log('I am ' + this.age + ' years old.') +} +Manager.howOldAmI = howOldAmI; +Manager.howOldAmI() // I am 27 years old. +</pre> + +<h2 id="Defining_getters_and_setters" name="Defining_getters_and_setters">ゲッターとセッターの定義</h2> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Functions/get">ゲッター</a>は、特定のプロパティの値を取得するメソッドです。<a href="/ja/docs/Web/JavaScript/Reference/Functions/set">セッター</a> は、特定のプロパティの値を設定するメソッドです。ゲッターとセッターは、新しいプロパティの追加をサポートする定義済みのコアオブジェクト、またはユーザー定義オブジェクト上で定義できます。</p> + +<p>ゲッターとセッターは次のどちらの方法でも作れます。</p> + +<ul> + <li><a href="#Object_initializers">オブジェクト初期化子</a>を使用して定義する。</li> + <li>ゲッターやセッターを追加するメソッドを使用して、任意のオブジェクトへ後から追加する。</li> +</ul> + +<p><a href="#Object_initializers">オブジェクト初期化子</a>を使用してゲッターとセッターを定義するには、ゲッターメソッドの前に <code>get</code> を、セッターメソッドの前に <code>set</code> を記述するだけです。当然ですがゲッターメソッドは引数を想定してはいけませんし、セッターメソッドは正確に 1 つの引数(新しい設定値)を期待します。 +例えば、以下のようになります。</p> + +<pre class="brush: js notranslate">var o = { + a: 7, + get b() { + return this.a + 1; + }, + set c(x) { + this.a = x / 2; + } +}; + +console.log(o.a); // 7 +console.log(o.b); // 8 <-- この時点で get b() メソッドが開始されます。initiated. +o.c = 50; // <-- この時点で set c(x) メソッドが開始されます。 +console.log(o.a); // 25 +</pre> + +<p><code>o</code> オブジェクトのプロパティは以下の通りです。</p> + +<ul> + <li><code>o.a</code> — 数値</li> + <li><code>o.b</code> — <code>o.a</code> + 1 を返すゲッター</li> + <li><code>o.c</code> — <code>o.c</code> に設定される値を 1/2 にしたものを <code>o.a</code> に設定するセッター</li> +</ul> + +<p><code>[gs]et <em>propertyName</em>(){ }</code> という構文により誤解を招くかもしれませんが、オブジェクトリテラル内で "[gs]et <em>property</em>()" によって定義されたゲッターやセッターの関数名は、(<code>__define[GS]etter__</code> とは対照的に)ゲッターやセッター自体の名前ではないことに注意してください。</p> + +<p>ゲッターとセッターはまた、<code>Object.defineProperties</code> メソッドを使用して、生成後のオブジェクトにいつでも追加できます。このメソッドの第1引数はゲッターまたはセッターを定義するオブジェクトです。第2引数はプロパティ名がゲッターまたはセッターの名前で、プロパティ値がゲッターまたはセッター関数を定義するオブジェクトです。前回の例と同じゲッターとセッターを定義する例を見てみましょう。</p> + +<pre class="brush: js notranslate">var o = { a: 0 }; + +Object.defineProperties(o, { + 'b': { get: function() { return this.a + 1; } }, + 'c': { set: function(x) { this.a = x / 2; } } +}); + +o.c = 10; // 'a' プロパティに 10 / 2 (5) を代入するセッターを実行します +console.log(o.b); // a + 1 つまり 6 を与えるゲッターを実行します +</pre> + +<p>2 つの方法のどちらを選ぶのかは、自身のプログラミングスタイルや行っている作業によります。すでにオブジェクト初期化子を気に入っているのなら、プロトタイプの定義時にほとんどの場合、最初の書式を選ぶでしょう。この書式はより簡潔で自然です。しかしながら、ゲッターやセッターを後から追加しなければならないとき — 自分がプロトタイプやオブジェクトの詳細を書いていない場合 — には、2番目の書式だけが使えます。2番目の書式には JavaScript の動的な性質が表現されています — ただし、コードを読みにくく理解しづらいものにする可能性があります。</p> + +<h2 id="Deleting_properties" name="Deleting_properties">プロパティの削除</h2> + +<p>継承されたものでないプロパティは {{jsxref("Operators/delete","delete")}} 演算子を使って削除できます。以下のコードはプロパティを削除する方法です。</p> + +<pre class="brush: js notranslate">// 2 つのプロパティ a と b を持つ新しいオブジェクト myobj を作成。 +var myobj = new Object; +myobj.a = 5; +myobj.b = 12; + +// プロパティ a を削除すると、myobj には b プロパティだけが残る。 +delete myobj.a; +console.log ('a' in myobj); // yields "false" +</pre> + +<p><code>delete</code> 演算子はまた、<code>var</code> キーワードを使わずに定義されたグローバル変数の削除にも使えます。</p> + +<pre class="brush: js notranslate">g = 17; +delete g; +</pre> + +<h2 id="Comparing_Objects" name="Comparing_Objects">オブジェクトの比較</h2> + +<p>JavaScript では、オブジェクトは参照型です。2 つの異なるオブジェクトは、同じプロパティを持っていても等値とは見なされません。同じオブジェクトへの参照を比較した時のみ真となります。</p> + +<pre class="brush: js notranslate">// 2 つの変数は、同じプロパティを持つ 2 つの異なるオブジェクト +var fruit = {name: 'apple'}; +var fruitbear = {name: 'apple'}; + +fruit == fruitbear; // false が返される +fruit === fruitbear; // false が返される</pre> + +<pre class="brush: js notranslate">// 2 つの変数、オブジェクトは 1 つ +var fruit = {name: 'apple'}; +var fruitbear = fruit; // fruitbear に fruit オブジェクトへの参照を代入 + +// fruit と fruitbear は同じオブジェクトを指している +fruit == fruitbear; // true が返される +fruit === fruitbear; // true が返される + +fruit.name = 'grape'; +console.log(fruitbear); // { name: "apple" } ではなく { name: "grape" } と出力される +</pre> + +<p>比較演算子についての詳細は、リファレンスの<a href="/ja/docs/Web/JavaScript/Reference/Operators/Comparison_Operators">比較演算子</a>の節をご覧ください。</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>より詳しく知りたければ、当ガイドの<a href="/ja/docs/Web/JavaScript/Guide/Details_of_the_Object_Model">オブジェクトモデルの詳細</a>をお読みください。</li> + <li>ECMAScript 2015 のクラス (オブジェクトを作る新しい方法) について知りたければ、リファレンスの <a href="/ja/docs/Web/JavaScript/Reference/Classes">JavaScript クラス</a>の節をお読みください。</li> +</ul> + +<p>{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}</p> diff --git a/files/ja/web/javascript/guide/writing_a_regular_expression_pattern/index.html b/files/ja/web/javascript/guide/writing_a_regular_expression_pattern/index.html new file mode 100644 index 0000000000..64da075317 --- /dev/null +++ b/files/ja/web/javascript/guide/writing_a_regular_expression_pattern/index.html @@ -0,0 +1,193 @@ +--- +title: 正規表現パターンの記述 +slug: Web/JavaScript/Guide/Writing_a_Regular_Expression_Pattern +--- +<h3 id=".E6.AD.A3.E8.A6.8F.E8.A1.A8.E7.8F.BE.E3.83.91.E3.82.BF.E3.83.BC.E3.83.B3.E3.82.92.E6.9B.B8.E3.81.8F" name=".E6.AD.A3.E8.A6.8F.E8.A1.A8.E7.8F.BE.E3.83.91.E3.82.BF.E3.83.BC.E3.83.B3.E3.82.92.E6.9B.B8.E3.81.8F">正規表現パターンを書く</h3> + +<p>正規表現パターンは、<code>/abc/</code> のような単純な文字、または <code>/ab*c/</code> や <code>/Chapter (\d+)\.\d*/</code> のような単純な文字と特殊文字との組み合わせからなります。最後の例では記憶装置として使われている丸括弧が含まれています。パターンのこの部分でなされたマッチは後で使用できるように記憶されます。詳しくは <a href="/ja/docs/JavaScript/Guide/Working_with_Regular_Expressions/Using_Parenthesized_Substring_Matches" title="ja/docs/JavaScript/Guide/Working_with_Regular_Expressions/Using_Parenthesized_Substring_Matches">括弧で囲まれた部分文字列のマッチの使用</a> を参照してください。</p> + +<h4 id="単純なパターンの使用">単純なパターンの使用</h4> + +<p>単純なパターンは、直接マッチしている部分を見つけたい文字で構成されます。例えば、/abc/ というパターンは、実際に 'abc' という文字が一緒にその順で存在しているときにだけ、文字列中の文字の組み合わせにマッチします。"Hi, do you know your abc's?" や "The latest airplane designs evolved from slabcraft." といった文字列でのマッチは成功します。どちらの場合でも 'abc' という部分文字列にマッチします。"Grab crab" という文字列では 'abc' という部分文字列が含まれていないためマッチしません。</p> + +<h4 id="特殊文字の使用">特殊文字の使用</h4> + +<p>1 つ以上の b を見つけたり、ホワイトスペースを見つけたりといった直接マッチより高度なマッチの検索では、パターンに特殊文字を使用します。例えば <code>/ab*c/</code> というパターンでは 1 つの 'a' とその後ろに続く 0 個以上の 'b'(* は直前のアイテムの 0 回以上の出現を意味する)とそのすぐ後ろに続く 'c' からなる文字の組み合わせにマッチします。"cbbabbbbcdebc" という文字列ではこのパターンは 'abbbbc' という部分文字列にマッチします。</p> + +<p>以下の表で正規表現で使用できる特殊文字とその意味を詳しく説明します。</p> + +<table class="fullwidth-table"> + <tbody> + <tr> + <th>文字</th> + <th>意味</th> + </tr> + <tr> + <td>\</td> + <td>次のうちのどちらか。 + <ul> + <li>通常は文字どおり扱われる文字に対して、次の文字は特殊であり、文字どおりに解釈すべきではないと指示する。例えば、<code>/b/ </code> は 'b' という文字にマッチする。b の前にバックスラッシュを置き、<code>/\b/</code> とすると、その文字は単語の区切りにマッチすることを意味する特殊文字になる。</li> + <li>通常は特殊文字として扱われる文字に対して、次の文字は特殊ではなく、文字どおりに解釈すべきであると指示する。例えば、* は直前のアイテムの 0 回以上の出現にマッチさせることを意味する特殊文字である。つまり、例えば <code>/a*/</code> は a の 0 文字以上の a へのマッチを意味する。* という文字そのものにマッチさせるには、その直前にバックスラッシュを置く。例えば、<code>/a\*/</code> は 'a*' にマッチする。</li> + </ul> + </td> + </tr> + <tr> + <td>^</td> + <td>入力の先頭にマッチする。複数行フラグが true にセットされている場合は、改行文字直後にもマッチする。 例えば、<code>/^A/</code> は "an A" の 'A' にはマッチしないが、"An A" の最初の 'A' にはマッチする。</td> + </tr> + <tr> + <td>$</td> + <td>入力の末尾にマッチする。複数行フラグが true にセットされている場合は、改行文字直前にもマッチする。 例えば、<code>/t$/</code> は "eater" の 't' にはマッチしないが、"eat" の 't' にはマッチする。</td> + </tr> + <tr> + <td>*</td> + <td>直前の文字の 0 回以上の繰り返しにマッチする。 例えば、<code>/bo*/</code> は "A ghost booooed" の 'boooo' や "A bird warbled" の 'b' にはマッチするが、"A goat grunted" ではマッチしない。</td> + </tr> + <tr> + <td>+</td> + <td>直前の文字の 1 回以上の繰り返しにマッチする。{1,} と同等。 例えば、<code>/a+/</code> は "candy" の 'a' や、"caaaaaaandy" のすべての a にマッチする。</td> + </tr> + <tr> + <td>?</td> + <td>直前の文字の 0 回か 1 回の繰り返しにマッチする。 + <p>例えば、<code>/e?le?/</code> は "angel" の 'el' や "angle" の 'le' にマッチする。</p> + + <p><span class="nowiki">*</span>、+、?、{} といった量指定子の直後に使用した場合、その量指定子をスキップ優先(最小回数にマッチ)にする。これはデフォルトとは逆であり、デフォルトは繰り返し優先(最大回数にマッチ)。例えば、/\d+/ は非グローバルで "123abc" の "123" にマッチするが、/\d+?/ の場合、"1" だけにマッチする。</p> + 先読み表現内でも使用できるが、これはこの表の x(?=y) および x(?!y) にて説明。</td> + </tr> + <tr> + <td>.</td> + <td>小数点は改行文字以外のどの 1 文字にもマッチする。 例えば、<code>/.n/</code> は "nay, an apple is on the tree" の 'an' や 'on' にはマッチするが、'nay' にはマッチしない。</td> + </tr> + <tr> + <td>(x)</td> + <td>'x' にマッチし、マッチしたものを記憶しておく。これはキャプチャする括弧と呼ぶ。 例えば、<code>/(foo)/</code> は "foo bar" の 'foo' にマッチし、これを記憶する。マッチした部分文字列は結果として生成される配列の要素 1, ..., b から参照できる。</td> + </tr> + <tr> + <td>(?:x)</td> + <td>'x' にマッチするが、マッチしたものは記憶しない。これはキャプチャしない括弧と呼ぶ。マッチした部分文字列は先程のような配列の要素 1, ..., n から参照することはできない。</td> + </tr> + <tr> + <td>x(?=y)</td> + <td>'x' に 'y' が続く場合のみ 'x' にマッチする。例えば、<code>/Jack(?=Sprat)/</code> は 'Jack' の後ろに 'Sprat' が続く場合のみ 'Jack' にマッチする。<code>/Jack(?=Sprat|Frost)/</code> は 'Jack' の後ろに 'Sprat' または 'Frost' が続く場合のみ 'Jack' にマッチする。しかしながら、'Sprat' も 'Frost' もマッチの結果には現れない。</td> + </tr> + <tr> + <td>x(?!y)</td> + <td>'x' に 'y' が続かない場合のみ 'x' にマッチする。例えば、<code>/\d+(?!\.)/</code> はある数に小数点が続かない場合のみその数にマッチする。正規表現 <code>/\d+(?!\.)/.exec("3.141")</code> は 141 にはマッチするが 3.141 にはマッチしない。</td> + </tr> + <tr> + <td>x|y</td> + <td>'x' または 'y' にマッチする。 例えば、<code>/green|red/</code> は "green apple" の "green' や "red apple" の 'red' にマッチする。</td> + </tr> + <tr> + <td>{n}</td> + <td>n には正の整数が入る。直前の文字がちょうど n 回出現するものにマッチする。 例えば、<code>/a{2}/</code> は "candy" の 'a' にはマッチしないが、"caandy" の すべての a にマッチする。また、"caaandy" の最初の 2 つの a にマッチする。</td> + </tr> + <tr> + <td>{n,}</td> + <td>n には正の整数が入る。直前の文字が少なくとも n 回出現するものにマッチする。 例えば、<code>/a{2,}/</code> は "candy" の 'a' にはマッチしないが、"caandy" や "caaaaaaandy" の すべての a にマッチする。</td> + </tr> + <tr> + <td>{n,m}</td> + <td>n および m には正の整数が入る。直前の文字が少なくとも n 回、多くとも m 回出現するものにマッチする。 例えば、<code>/a{1,3}/</code> は "cndy" ではマッチせず、"candy" の 'a'、"caandy" の最初の 2 つの a、"caaaaaaandy" の最初の 3 つの a にマッチする。"caaaaaaandy" では元の文字列に a が 4 つ以上あるが、マッチするのは "aaa" であることに注意。</td> + </tr> + <tr> + <td>[xyz]</td> + <td>文字の集合。囲まれた文字のどれにでもマッチする。ハイフンを用いて文字の範囲を指定することも可能。 例えば、<code>/[abcd]/</code> は <code>/[a-d]/</code> と同じ。これは "brisket" の 'b' や "city" の 'c' にマッチする。</td> + </tr> + <tr> + <td>[^xyz]</td> + <td>文字の集合の否定または補集合。角括弧で囲まれていないものにマッチする。ハイフンを用いて文字の範囲を指定することも可能。 例えば、<code>/[^abc]/</code> は <code>/[^a-c]/</code> と同じ。これは "brisket" の 'r' や "chop" の 'h' にマッチする。</td> + </tr> + <tr> + <td>[\b]</td> + <td>後退にマッチする。(\b と混同してはならない。)</td> + </tr> + <tr> + <td>\b</td> + <td>スペースや改行文字のような単語の区切りにマッチする。([\b] と混同してはならない。) 例えば、<code>/\bn\w/</code> は "noonday" の 'no' にマッチする。また、<code>/\wy\b/</code> は "possibly yesterday" の 'ly' にマッチする。</td> + </tr> + <tr> + <td>\B</td> + <td>単語の区切り以外の文字にマッチする。 例えば、<code>/\w\Bn/</code> は "noonday" の 'on' にマッチする。また、<code>/y\B\w/</code> は "possibly yesterday" の 'ye' にマッチする。</td> + </tr> + <tr> + <td>\cX</td> + <td>X には制御文字が入る。文字列中の制御文字にマッチする。 例えば、<code>/\cM/</code> は文字列中の control-M にマッチする。</td> + </tr> + <tr> + <td>\d</td> + <td>数字にマッチする。<code>[0-9]</code> と同等。 例えば、<code>/\d/</code> や <code>/[0-9]/</code> は "B2 is the suite number" の '2' にマッチする。</td> + </tr> + <tr> + <td>\D</td> + <td>数字以外の文字にマッチする。<code>[^0-9]</code> と同等。 例えば、<code>/\D/</code> や <code>/[^0-9]/</code> は "B2 is the suite number" の 'B' にマッチする。</td> + </tr> + <tr> + <td>\f</td> + <td>改ページにマッチする。</td> + </tr> + <tr> + <td>\n</td> + <td>改行にマッチする。</td> + </tr> + <tr> + <td>\r</td> + <td>復帰にマッチする。</td> + </tr> + <tr> + <td>\s</td> + <td>スペース、タブ、改ページ、改行を含む、1 つのホワイトスペース文字にマッチする。 <code>[ \f\n\r\t\v\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]</code> と同等。 例えば、<code>/\s\w*/</code> は "foo bar" の ' bar' にマッチする。</td> + </tr> + <tr> + <td>\S</td> + <td>ホワイトスペース以外の 1 文字にマッチする。<code>[^ \f\n\r\t\v\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]</code> と同等。 例えば、<code>/\S\w*/</code> は "foo bar" の 'foo' にマッチする。</td> + </tr> + <tr> + <td>\t</td> + <td>タブにマッチする。</td> + </tr> + <tr> + <td>\v</td> + <td>垂直タブにマッチする。</td> + </tr> + <tr> + <td>\w</td> + <td>アンダースコアを含むどの英数字にもマッチする。<code>[A-Za-z0-9_]</code> と同等。 例えば、<code>/\w/</code> は "apple" の 'a' や "$5.28" の '5' や "3D" の '3' にマッチする。</td> + </tr> + <tr> + <td>\W</td> + <td>前述以外の文字にマッチする。<code>[^A-Za-z0-9_]</code> と同等。 例えば、<code>/\W/</code> や <code>/[^$A-Za-z0-9_]/</code> は "50%" の '%' にマッチする。</td> + </tr> + <tr> + <td>\n</td> + <td>n には正の整数が入る。その正規表現の n 番目の括弧の部分にマッチする最後の部分文字列への後方参照(左括弧をカウントする)。 例えば、<code>/apple(,)\sorange\1/</code> は "apple, orange, cherry, peach" の 'apple, orange,' にマッチする。</td> + </tr> + <tr> + <td>\0</td> + <td>NUL 文字にマッチする。この後ろに他の数字を続けてはならない。</td> + </tr> + <tr> + <td>\xhh</td> + <td>hh(2 桁の 16 進数)というコードを持つ文字にマッチする。</td> + </tr> + <tr> + <td>\uhhhh</td> + <td>hhhh(4 桁の 16 進数)というコードを持つ文字にマッチする。</td> + </tr> + </tbody> +</table> + +<p><small><strong>表 4.1正規表現における特殊文字</strong></small></p> + +<h4 id="括弧の使用">括弧の使用</h4> + +<p>正規表現パターンの一部分を括弧で囲むことで、マッチした部分文字列のその部分を記憶しておくことができます。一度記憶すると、後からその部分文字列を呼び戻すことができます。これに関しては <a href="/ja/Core_JavaScript_1.5_Guide/Working_with_Regular_Expressions/Using_Parenthesized_Substring_Matches" title="ja/Core_JavaScript_1.5_Guide/Working_with_Regular_Expressions/Using_Parenthesized_Substring_Matches">括弧で囲まれた部分文字列のマッチの使用</a> で説明しています。</p> + +<p>例えば、<code>/Chapter (\d+)\.\d*/</code> というパターンでは、エスケープされた文字と特殊文字の部分がその例で、その部分を記憶するように指示しています。これは 'Chapter ' という文字列、それに続く 1 文字以上の数字(\d はいずれかの数字を意味し、+ は 1 回以上の繰り返しを意味する)、それに続く小数点(それ自体は特殊文字であり、小数点の前の \ はパターンが '.' という文字そのものを探すようにすることを意味する)、それに続く 0 文字以上の数字(\d は数字を意味し、* は 0 回以上の繰り返しを意味する)にマッチします。さらに、括弧を使うことで最初のマッチした数値を記憶させます。</p> + +<p>このパターンは "Open Chapter 4.3, paragraph 6" という文字列で見つかり、'4' が記憶されます。このパターンは "Chapter 3 and 4" では見つかりません。この文字列は '3' の後ろにピリオドがないためです。</p> + +<p>マッチした部分を記憶させることなく部分文字列にマッチさせたい場合は、その括弧においてパターンの前に <code>?:</code> を付けてください。例えば、<code>(?:\d+)</code> は 1 文字以上の数字にマッチしますが、マッチした文字は記憶されません。</p> + +<p>{{ PreviousNext("JavaScript/Guide/Creating_a_Regular_Expression", "JavaScript/Guide/Working_with_Regular_Expressions") }}</p> |