From 47ad2714769652bd3bdc0d9fecbe07c5a4f787de Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Sun, 25 Apr 2021 00:09:57 +0900 Subject: Web/JavaScript/Reference/Functions を更新 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 「原語併記」マクロを廃止 - 2021/02/20 時点の英語版に同期 --- .../web/javascript/reference/functions/index.html | 401 ++++++++++----------- 1 file changed, 191 insertions(+), 210 deletions(-) (limited to 'files/ja') diff --git a/files/ja/web/javascript/reference/functions/index.html b/files/ja/web/javascript/reference/functions/index.html index a9e3cee514..93f8b94e20 100644 --- a/files/ja/web/javascript/reference/functions/index.html +++ b/files/ja/web/javascript/reference/functions/index.html @@ -12,21 +12,21 @@ translation_of: Web/JavaScript/Reference/Functions ---
{{jsSidebar("Functions")}}
-

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

+

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

-

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

+

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

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

-

解説

+

解説

-

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

+

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

-

初期値以外の値を返すためには、返す値を指定する return 文が関数内になくてはなりません。return 文を持たない関数は初期値を返します。new キーワードとともに constructor が呼び出された場合、その this パラメータが初期値となります。それ以外の全ての関数がデフォルトで返す値は {{jsxref("undefined")}} です。

+

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

-

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

+

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

-
 /* 関数 'myFunc' を宣言 */
+
 /* 関数 'myFunc' を宣言 */
 function myFunc(theObject) {
   theObject.brand = "Toyota";
 }
@@ -49,138 +49,121 @@ console.log(mycar.brand);
 myFunc(mycar);
 
 /*
- * オブジェクトの 'brand' プロパティの値は関数によって変更されたので
- * 'Toyota' と出力される
+ * オブジェクトの 'brand' プロパティの値は関数によって
+ * 変更されたので 'Toyota' と出力される
  */
 console.log(mycar.brand);
 
-

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

+

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

-

関数を定義する

+

関数の定義

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

-

関数宣言 (function 文)

+

関数宣言 (function 文)

-

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

+

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

-
function name([param[, param[, ... param]]]) {
-   statements
+
function name([param[, param[, ... param]]]) {
+   statements
 }
 
-
name
-
関数名。
+
name
+
関数名です。
+
param
+
関数に渡される引数の名前です。
+
statements
+
関数の本体を構成する文です。
-
-
param
-
関数に渡される引数の名前です。
-
+

関数式 (function 式)

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

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

-

関数式 (function 演算子)

- -

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

- -
function [name]([param[, param[, ... param]]]) {
-   statements
+
function [name]([param[, param[, ... param]]]) {
+   statements
 }
 
-
name
-
関数名。省略する事ができ、その場合関数は無名関数と見なされます。
-
- -
-
param
-
関数に渡される引数の名前です。
-
statements
-
関数の本体を構成する文。
+
name
+
関数名。省略することができ、その場合は関数は無名関数と見なされます。
+
param
+
関数に渡される引数の名前です。
+
statements
+
関数の本体を構成する文です。
-

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

+

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

-
var myFunction = function() {
+
var myFunction = function() {
     statements
 }
-

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

+

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

-
var myFunction = function namedFunction(){
+
var myFunction = function namedFunction(){
     statements
 }
 

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

-

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

+

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

-

関数を一度だけ使うときの一般的なパターンが {{glossary("IIFE", "IIFE (Immediately Invokable Function Expression)")}} です。

+

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

-
(function() {
+
(function() {
     statements
 })();
-

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

+

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

-

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

+

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

-

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

+

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

-
function* name([param[, param[, ... param]]]) {
-   statements
+
function* name([param[, param[, ... param]]]) {
+   statements
 }
 
-
name
-
関数名。
-
- -
-
param
-
関数に渡される引数の名前です。
-
- -
-
statements
-
関数の本体を構成する文。
-
+
name
+
関数名。
+
param
+
関数に渡される引数の名前です。
+
statements
+
関数の本体を構成する文。
+ -

ジェネレーター関数式 (function* 演算子)

+

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

-

ジェネレーター関数式は、ジェネレーター関数宣言と似ており、同じ構文を持っています (詳細は {{jsxref('Operators/function*', 'function* 演算子')}} を参照してください)。

+

ジェネレーター関数式は、ジェネレーター関数宣言と似ており、同じ構文を持っています (詳細は {{jsxref('Operators/function*', 'function* 式')}} を参照してください)。

-
function* [name]([param[, param[, ... param]]]) {
-   statements
+
function* [name]([param[, param[, ... param]]]) {
+   statements
 }
 
-
name
-
関数名。省略する事ができ、その場合関数は無名関数と見なされます。
+
name
+
関数名。省略することができ、その場合関数は無名関数と見なされます。
+
param
+
関数に渡される引数の名前です。
+
statements
+
関数の本体を構成する文です。
-
-
param
-
関数に渡される引数の名前です。
-
statements
-
関数の本体を構成する文。
-
+

アロー関数式 (=>)

-

アロー関数式 (=>)

+

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

-

アロー関数式は短縮構文を持ち、また関数の this 値を語彙的に束縛します (詳細はアロー関数を参照):

- -
([param[, param]]) => {
+
([param[, param]]) => {
    statements
 }
 
@@ -188,175 +171,175 @@ param => expression
 
-
param
-
引数の名前。引数が 0 個の場合は () で示すことが必要です。引数が 1 個の場合のみ、丸括弧は必須ではありません。(例えば foo => 1)
-
statements または expression
-
複数の文は中括弧で括らなければなりません。単一の式では、中括弧は必須ではありません。式は、関数の暗黙的な戻り値でもあります。
+
param
+
引数の名前。引数が 0 個の場合は () で示すことが必要です。引数が 1 個の場合のみ、丸括弧は必須ではありません。(例えば foo => 1)
+
statements または expression
+
複数の文は中括弧で括らなければなりません。単一の式では、中括弧は必須ではありません。式は、関数の暗黙的な返値でもあります。
-

Function コンストラクタ

+

Function コンストラクター

-

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

+

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

-

他の全てのオブジェクトと同じように、new 演算子を使って {{jsxref("Function")}} オブジェクトを作成する事ができます。

+

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

-
new Function (arg1, arg2, ... argN, functionBody)
+
new Function (arg1, arg2, ... argN, functionBody)
 
-
arg1, arg2, ... argN
-
関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。
-
- -
-
functionBody
-
関数定義を構成する JavaScript 文を含む文字列。
+
arg1, arg2, ... argN
+
関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。
+
functionBody
+
関数定義を構成する JavaScript 文を含む文字列。
-

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

+

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

-

GeneratorFunction コンストラクタ

+

GeneratorFunction コンストラクター

-

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

+

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

-

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

+

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

-

他の全てのオブジェクトと同じように、new 演算子を使って {{jsxref("GeneratorFunction")}} オブジェクトを作成する事ができます。

+

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

-
new GeneratorFunction (arg1, arg2, ... argN, functionBody)
+
new GeneratorFunction (arg1, arg2, ... argN, functionBody)
 
-
arg1, arg2, ... argN
-
関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。例えば "x" 、"theValue"、もしくは "a,b" などです。
-
- -
-
functionBody
-
関数定義を構成する JavaScript 文を含む文字列。
+
arg1, arg2, ... argN
+
関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。例えば "x"、"theValue"、"a,b" などです。
+
functionBody
+
関数定義を構成する JavaScript 文を含む文字列です。
-

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

+

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

-

関数の引数

+

関数の引数

-

デフォルト引数

+

デフォルト引数

-

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

+

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

-

Rest parameters

+

残余引数

-

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

+

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

-

arguments オブジェクト

+

arguments オブジェクト

-

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

+

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

    -
  • arguments: 現在実行中の関数に渡された引数を格納する配列状オブジェクト。
  • -
  • arguments.callee : 現在実行中の関数。
  • -
  • arguments.caller : 現在実行中の関数を実行した関数。
  • -
  • arguments.length: 関数に渡された引数の数。
  • +
  • + arguments: + 現在実行中の関数に渡された引数を格納する配列状オブジェクト。
  • +
  • + arguments.callee : + 現在実行中の関数。
  • +
  • + arguments.caller : + 現在実行中の関数を実行した関数。
  • +
  • + arguments.length: + 関数に渡された引数の数。
-

メソッドを定義する

+

メソッドを定義する

-

getter と setter 関数

+

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

-

新しいプロパティの追加をサポートする、どの標準ビルトインオブジェクトあるいはユーザー定義オブジェクトにも、getter(accessor メソッド)や setter (mutator メソッド)を定義することができます。getter と setter を定義するための構文は、オブジェクトリテラル構文を使用します。

+

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

-
get
-
-

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

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

メソッド定義構文

+

メソッド定義構文

-

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

+

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

-
var obj = {
+
var obj = {
   foo() {},
   bar() {}
 };
-

コンストラクタか関数宣言か関数式か

+

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

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

-

Function コンストラクタによって定義され、変数 multiply に代入された関数:

+

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

-
var multiply = new Function('x', 'y', 'return x * y');
+
var multiply = new Function('x', 'y', 'return x * y');
-

multiply と命名された関数の 関数宣言:

+

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

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

変数 multiply に代入された、無名関数の関数式:

+

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

-
var multiply = function(x, y) {
+
var multiply = function(x, y) {
    return x * y;
 };
 
-

変数 multiply に代入された、func_name と命名された関数式:

+

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

-
var multiply = function func_name(x, y) {
+
var multiply = function func_name(x, y) {
    return x * y;
 };
 
-

相違点

+

相違点

-

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

+

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

-

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

+

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

-
var y = function x() {};
-alert(x); // エラーを投げる
+
var y = function x() {};
+alert(x); // エラーが発生する
 
-

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

+

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

-

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

+

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

-

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

+

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

-

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

+

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

-
function anonymous() {
+
function anonymous() {
 }
 

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

-
var foo = new Function("alert(anonymous);");
+
var foo = new Function("alert(anonymous);");
 foo();
 
-

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

+

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

-
foo(); // FOO! とアラートされる
+
foo(); // FOO! とアラート表示
 function foo() {
    alert('FOO!');
 }
 
-

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

+

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

-
/*
+
/*
  * Declare and initialize a variable 'p' (global)
  * and a function 'myFunc' (to change the scope) inside which
  * declare a varible with same name 'p' (current) and
@@ -392,21 +375,21 @@ myFunc();
  */
 
-

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

+

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

-

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

+

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

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

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

+

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

    -
  • 式の一部になった時
  • -
  • 関数またはスクリプト自体の「{{ 原語併記("ソース要素", "source element") }}」でなくなった時。「ソース要素」はスクリプトや関数本体の中で入れ子にされていない文の事です。
  • +
  • 式の一部になったとき
  • +
  • 関数またはスクリプト自体の「ソース要素 (source element)」でなくなったとき。「ソース要素」はスクリプトや関数本体の中で入れ子にされていない文の事です。
-
var x = 0;               // ソース要素
+
var x = 0;               // ソース要素
 if (x === 0) {           // ソース要素
    x = 10;               // ソース要素ではない
    function boo() {}     // ソース要素ではない
@@ -421,9 +404,9 @@ function foo() {         // ソース要素
 }
 
-

+

-
// 関数宣言
+
// 関数宣言
 function foo() {}
 
 // 関数式
@@ -432,13 +415,11 @@ function foo() {}
 // 関数式
 x = function hello() {}
 
-
 if (x) {
    // 関数式
    function world() {}
 }
 
-
 // 関数宣言
 function a() {
    // 関数宣言
@@ -450,11 +431,11 @@ function a() {
 }
 
-

ブロックレベル関数

+

ブロックレベル関数

-

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

+

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

-
'use strict';
+
'use strict';
 
 function f() {
   return 1;
@@ -471,13 +452,13 @@ f() === 1; // true
 // 非 strict モードでは f() === 2
 
-

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

+

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

-

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

+

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

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

-
if (shouldDefineZero) {
+
if (shouldDefineZero) {
    function zero() {     // 危険: 互換性リスク
       console.log("This is zero.");
    }
@@ -486,11 +467,11 @@ f() === 1; // true
 
 

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

-

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

+

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

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

-
var zero;
+
var zero;
 if (shouldDefineZero) {
    zero = function() {
       console.log("This is zero.");
@@ -498,13 +479,13 @@ if (shouldDefineZero) {
 }
 
-

+

-

フォーマットされた数値を返す

+

整形された数値を返す

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

-
// この関数は先頭にゼロを足して固定長にした文字列を返す
+
// この関数は先頭にゼロを足して固定長にした文字列を返す
 function padZeros(num, totalLen) {
    var numStr = num.toString();             // 戻り値を文字列に初期化する
    var numZeros = totalLen - numStr.length; // ゼロの数を計算する
@@ -517,17 +498,17 @@ function padZeros(num, totalLen) {
 
 

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

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

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

+

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

-

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

+

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

-
 if ('function' == typeof window.noFunc) {
+
 if ('function' == typeof window.noFunc) {
    // noFunc() を使う
  } else {
    // 何か他のことをする
@@ -536,40 +517,40 @@ result = padZeros(5,4);  // "0005" を返す
 
 

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

-

仕様

+

仕様書

- - - - - - - - + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}
仕様書
{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}
-

ブラウザーの互換性

- - +

ブラウザーの互換性

{{Compat("javascript.functions")}}

-

関連情報

+

関連情報

    -
  • {{jsxref("Statements/function", "function 文")}}
  • -
  • {{jsxref("Operators/function", "function 演算子")}}
  • -
  • {{jsxref("Statements/function*", "function* 文")}}
  • -
  • {{jsxref("Operators/function*", "function* 演算子")}}
  • -
  • {{jsxref("Function")}}
  • -
  • {{jsxref("GeneratorFunction", "ジェネレーター関数")}}
  • -
  • {{jsxref("Functions/Arrow_functions", "アロー関数")}}
  • -
  • {{jsxref("Functions/Default_parameters", "デフォルト引数")}}
  • -
  • {{jsxref("Functions/rest_parameters", "Rest parameters")}}
  • -
  • {{jsxref("Functions/arguments", "arguments オブジェクト")}}
  • -
  • {{jsxref("Functions/get", "getter")}}
  • -
  • {{jsxref("Functions/set", "setter")}}
  • -
  • {{jsxref("Functions/Method_definitions", "メソッド定義")}}
  • -
  • 関数と関数スコープ
  • +
  • {{jsxref("Statements/function", "function 文")}}
  • +
  • {{jsxref("Operators/function", "function 式")}}
  • +
  • {{jsxref("Statements/function*", "function* 文")}}
  • +
  • {{jsxref("Operators/function*", "function* 式")}}
  • +
  • {{jsxref("Function")}}
  • +
  • {{jsxref("GeneratorFunction", "ジェネレーター関数")}}
  • +
  • {{jsxref("Functions/Arrow_functions", "アロー関数")}}
  • +
  • {{jsxref("Functions/Default_parameters", "デフォルト引数")}}
  • +
  • {{jsxref("Functions/rest_parameters", "残余引数")}}
  • +
  • {{jsxref("Functions/arguments", "arguments オブジェクト")}}
  • +
  • {{jsxref("Functions/get", "getter")}}
  • +
  • {{jsxref("Functions/set", "setter")}}
  • +
  • {{jsxref("Functions/Method_definitions", "メソッド定義")}}
  • +
  • 関数と関数スコープ
-- cgit v1.2.3-54-g00ecf