1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
|
---
title: 関数
slug: Web/JavaScript/Reference/Functions
tags:
- Function
- Functions
- Guide
- JavaScript
- Parameter
- parameters
translation_of: Web/JavaScript/Reference/Functions
---
<div>{{jsSidebar("Functions")}}</div>
<p>一般的に言うと、関数とは外部 (再帰の場合は内部) から <em>呼ばれる</em> ことのできる「サブプログラム」です。プログラムそのもののように、関数は<em>{{ 訳語("関数本体", "function body") }}</em>と呼ばれる連続した文で構成されます。値を関数に <em>渡す</em> 事ができ、関数は値を<em>返す</em>事ができます。</p>
<p>JavaScript において、関数は第一級オブジェクトです。すなわち、関数はオブジェクトであり、他のあらゆるオブジェクトと同じように操作したり渡したりする事ができます。具体的には、関数は <code><a href="/ja/docs/JavaScript/Reference/Global_Objects/Function" title="Ja/JavaScript/Reference/Global_Objects/Function">Function</a></code> オブジェクトです。</p>
<p>より詳細な例や解説については、<a href="/ja/docs/Web/JavaScript/Guide/Functions">JavaScript の関数のガイド</a>を参照してください。</p>
<h2 id="Description" name="Description">解説</h2>
<p>JavaScript における全ての関数は、実際には <code>Function</code> オブジェクトです。<code>Function</code> オブジェクトのプロパティとメソッドについての情報は {{jsxref("Function")}} をご覧ください。</p>
<p>初期値以外の値を返すためには、返す値を指定する <code><a href="/ja/docs/JavaScript/Reference/Statements/return" title="Ja/JavaScript/Reference/Statements/return">return</a></code> 文が関数内になくてはなりません。<code>return</code> 文を持たない関数は初期値を返します。<code><a href="/ja/docs/JavaScript/Reference/Operators/new">new</a></code> キーワードとともに <a href="/ja/docs/JavaScript/Reference/Global_Objects/Object/constructor" title="JavaScript/Reference/Global_Objects/Object/constructor">constructor</a> が呼び出された場合、その <code>this</code> パラメータが初期値となります。それ以外の全ての関数がデフォルトで返す値は {{jsxref("undefined")}} です。</p>
<p>関数の仮引数 (パラメータ) には、関数呼び出しにおいて実引数 (アーギュメント) が渡されます。実引数は、関数に「<em>値渡し</em>」されます: 関数の中で引数の値を変更しても、その変更はグローバルスコープもしくは呼び出し元の関数内には反映されません。オブジェクト参照も「値」ですが、こちらは特別です: 参照されているオブジェクトのプロパティを関数の中で変更すると、次の例にあるように、その変更を関数の外部から見ることができます:</p>
<pre class="brush: js notranslate"> /* 関数 'myFunc' を宣言 */
function myFunc(theObject) {
theObject.brand = "Toyota";
}
/*
* 変数 'mycar' を宣言
* 新しいオブジェクトの生成と初期化
* 'mycar' への参照をオブジェクトに代入
*/
var mycar = {
brand: "Honda",
model: "Accord",
year: 1998
};
/* 'Honda' を出力 */
console.log(mycar.brand);
/* オブジェクト参照を関数に渡す */
myFunc(mycar);
/*
* オブジェクトの 'brand' プロパティの値は関数によって変更されたので
* 'Toyota' と出力される
*/
console.log(mycar.brand);
</pre>
<p><a href="/ja/docs/JavaScript/Reference/Operators/this" title="JavaScript/Reference/Operators/this"><code>this</code> キーワード</a>は現在実行中の関数を参照しません。よって、関数内部であっても、名前によって <code>Function</code> オブジェクトを参照しなければなりません。</p>
<h2 id="Defining_functions" name="Defining_functions">関数を定義する</h2>
<p>関数を定義するのにはいくつかの方法があります。</p>
<h3 id="The_function_declaration_function_statement" name="The_function_declaration_function_statement">関数宣言 (<code>function</code> 文)</h3>
<p>関数を宣言するための特殊な構文があります。(詳細は <a href="/ja/docs/JavaScript/Reference/Statements/function" title="Ja/JavaScript/Reference/Statements/function">function 文</a>を参照)</p>
<pre class="syntaxbo notranslatex notranslate">function <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>関数名。</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>関数に渡される引数の名前です。</dd>
</dl>
<dl>
<dt><code>statements</code></dt>
<dd>関数の本体を構成する文。</dd>
</dl>
<h3 id="The_function_expression_function_expression" name="The_function_expression_function_expression">関数式 (<code>function</code> 演算子)</h3>
<p>関数式は、関数宣言と似ており、同じ構文を持っています (詳細は <a href="/ja/docs/JavaScript/Reference/Operators/Special_Operators/function_Operator" title="ja/JavaScript/Reference/Operators/Special_Operators/function_Operator">function 演算子</a>を参照)。関数式はより大きな式の一部になることもあります。「名前付き」の関数式を定義することもできます(例えばその名前はコールスタック内で使われるかもしれません)し、「無名の」関数式を定義することもできます。関数式はスコープの開始時に「巻き上げ」られないので、コード内でそれらが登場するより前に使用することはできません。</p>
<pre class="syntaxbox notranslate">function [<em>name</em>]([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>関数名。省略する事ができ、その場合関数は無名関数と見なされます。</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>関数に渡される引数の名前です。</dd>
<dt><code>statements</code></dt>
<dd>関数の本体を構成する文。</dd>
</dl>
<p>以下は<strong>無名の</strong>関数式(名前が使われていない)の例です。</p>
<pre class="brush: js notranslate">var myFunction = function() {
statements
}</pre>
<p><strong>名前付きの</strong>関数式を作るため、定義の中で名前を提供することも可能です。</p>
<pre class="brush: js notranslate">var myFunction = function namedFunction(){
statements
}
</pre>
<p>名前付きの関数式を作ることのメリットの 1 つは、エラーに遭遇したとき、スタックトレースがその関数の名前を含めるため、エラーの発生源をより容易に特定できるということです。</p>
<p>ここまで見てきたように、どちらの例も <code>function</code> キーワードから開始されていません。<code>function</code> から開始せずに関数を含んでいる文が関数式です。</p>
<p>関数を一度だけ使うときの一般的なパターンが {{glossary("IIFE", "IIFE (Immediately Invokable Function Expression)")}} です。</p>
<pre class="brush: js notranslate">(function() {
statements
})();</pre>
<p>即時関数は、関数を宣言した直後に実行する関数式です。</p>
<h3 id="The_generator_function_declaration_function*_statement" name="The_generator_function_declaration_function*_statement">ジェネレーター関数宣言 (<code>function*</code> 文)</h3>
<p>ジェネレーター関数の宣言のための特別な構文です(詳細は {{jsxref('Statements/function*', 'function* 文')}} を参照してください)。</p>
<pre class="syntaxbox notranslate">function* <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>関数名。</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>関数に渡される引数の名前です。</dd>
</dl>
<dl>
<dt><code>statements</code></dt>
<dd>関数の本体を構成する文。</dd>
</dl>
<h3 id="The_generator_function_expression_function*_expression" name="The_generator_function_expression_function*_expression">ジェネレーター関数式 (<code>function*</code> 演算子)</h3>
<p>ジェネレーター関数式は、ジェネレーター関数宣言と似ており、同じ構文を持っています (詳細は {{jsxref('Operators/function*', 'function* 演算子')}} を参照してください)。</p>
<pre class="syntaxbox notranslate">function* [<em>name</em>]([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>関数名。省略する事ができ、その場合関数は無名関数と見なされます。</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>関数に渡される引数の名前です。</dd>
<dt><code>statements</code></dt>
<dd>関数の本体を構成する文。</dd>
</dl>
<h3 id="The_arrow_function_expression_>" name="The_arrow_function_expression_>">アロー関数式 (=>)</h3>
<p>アロー関数式は短縮構文を持ち、また関数の this 値を語彙的に束縛します (詳細は<a href="/ja/docs/JavaScript/Reference/arrow_functions">アロー関数</a>を参照):</p>
<pre class="syntaxbox notranslate">([param[, param]]) => {
statements
}
param => expression
</pre>
<dl>
<dt><code>param</code></dt>
<dd>引数の名前。引数が 0 個の場合は <code>()</code> で示すことが必要です。引数が 1 個の場合のみ、<span class="mw-headline" id="Parentheses_.28_.29">丸括弧</span>は必須ではありません。(例えば <code>foo => 1</code>)</dd>
<dt><code>statements または expression</code></dt>
<dd>複数の文は中括弧で括らなければなりません。単一の式では、中括弧は必須ではありません。式は、関数の暗黙的な戻り値でもあります。</dd>
</dl>
<h3 id="The_Function_constructor" name="The_Function_constructor"><code>Function</code> コンストラクタ</h3>
<div class="note">
<p><strong>メモ:</strong> <code>Function</code> コンストラクターによる関数の生成は推奨されません。これは、文字列として関数本体が必要で、JS エンジンによる最適化を妨げたり、他の問題を引き起こしたりする場合があるためです。</p>
</div>
<p>他の全てのオブジェクトと同じように、<code>new</code> 演算子を使って {{jsxref("Function")}} オブジェクトを作成する事ができます。</p>
<pre class="syntaxbox notranslate">new Function (<em>arg1</em>, <em>arg2</em>, ... <em>argN</em>, <em>functionBody</em>)
</pre>
<dl>
<dt><code>arg1, arg2, ... arg<em>N</em></code></dt>
<dd>関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。</dd>
</dl>
<dl>
<dt><code>functionBody</code></dt>
<dd>関数定義を構成する JavaScript 文を含む文字列。</dd>
</dl>
<p><code>Function</code> コンストラクタを関数として (<code>new</code> 演算子を使わずに) 呼び出しても、コンストラクタとして呼び出すのと同じ効果があります。</p>
<h3 id="The_GeneratorFunction_constructor" name="The_GeneratorFunction_constructor"><code>GeneratorFunction</code> コンストラクタ</h3>
<div class="note">
<p><strong>メモ:</strong> <code>GeneratorFunction</code> はグローバルオブジェクトではありませんが、ジェネレーター関数のインスタンスから得ることができます(詳細は {{jsxref("GeneratorFunction")}} を参照してください)。</p>
</div>
<div class="note">
<p><strong>メモ:</strong> <code>GeneratorFunction</code> コンストラクタによる関数の生成は推奨されません。これは、文字列として関数本体が必要で、JS エンジンによる最適化を妨げたり、他の問題を引き起こしたりする場合があるためです。</p>
</div>
<p>他の全てのオブジェクトと同じように、<code>new</code> 演算子を使って {{jsxref("GeneratorFunction")}} オブジェクトを作成する事ができます。</p>
<pre class="syntaxbox notranslate">new GeneratorFunction (<em>arg1</em>, <em>arg2</em>, ... <em>argN</em>, <em>functionBody</em>)
</pre>
<dl>
<dt><code>arg1, arg2, ... arg<em>N</em></code></dt>
<dd>関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。例えば "<code>x</code>" 、"<code>theValue</code>"、もしくは "<code>a,b</code>" などです。</dd>
</dl>
<dl>
<dt><code>functionBody</code></dt>
<dd>関数定義を構成する JavaScript 文を含む文字列。</dd>
</dl>
<p><code>Function</code> コンストラクタを関数として (<code>new</code> 演算子を使わずに) 呼び出しても、コンストラクタとして呼び出すのと同じ効果があります。</p>
<h2 id="The_arguments_object" name="The_arguments_object">関数の引数</h2>
<h3 id="Default_parameters" name="Default_parameters">デフォルト引数</h3>
<p>関数のデフォルト引数は、関数に値が渡されない場合や <code>undefined</code> が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。詳細は<a href="/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope/Default_parameters">デフォルト引数</a>を参照してください。</p>
<h3 id="Rest_parameters" name="Rest_parameters">Rest parameters</h3>
<p>rest parameters とは、不特定多数の引数を配列として受け取る構文です。詳細は <a href="/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope/rest_parameters">rest parameters</a> を参照してください。</p>
<h2 id="The_arguments_object" name="The_arguments_object"><code>arguments</code> オブジェクト</h2>
<p><code>arguments</code> オブジェクトを使って、関数内部で関数の引数を参照することができます。<a href="/ja/docs/JavaScript/Reference/Functions/arguments" title="Ja/JavaScript/Reference/Functions/arguments">arguments</a> を参照してください。</p>
<ul>
<li><code><a href="/ja/docs/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a></code>: 現在実行中の関数に渡された引数を格納する配列状オブジェクト。</li>
<li><code><a href="/ja/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee">arguments.callee</a></code> : 現在実行中の関数。</li>
<li><code><a href="/ja/docs/JavaScript/Reference/Functions_and_function_scope/arguments/caller">arguments.caller</a></code> : 現在実行中の関数を実行した関数。</li>
<li><code><a href="/ja/docs/JavaScript/Reference/Functions_and_function_scope/arguments/length">arguments.length</a></code>: 関数に渡された引数の数。</li>
</ul>
<h2 id="Scope_and_the_function_stack" name="Scope_and_the_function_stack">メソッドを定義する</h2>
<h3 id="Getter_and_setter_functions" name="Getter_and_setter_functions">getter と setter 関数</h3>
<p>新しいプロパティの追加をサポートする、どの標準ビルトインオブジェクトあるいはユーザー定義オブジェクトにも、getter(accessor メソッド)や setter (mutator メソッド)を定義することができます。getter と setter を定義するための構文は、オブジェクトリテラル構文を使用します。</p>
<dl>
<dt><a href="/ja/docs/Web/JavaScript/Reference/Functions/get">get</a></dt>
<dd>
<p>オブジェクトのプロパティを、そのプロパティが検索されたときに呼び出される関数に束縛します。</p>
</dd>
<dt><a href="/ja/docs/Web/JavaScript/Reference/Functions/set">set</a></dt>
<dd>オブジェクトのプロパティを、そのプロパティに代入しようとしたときに呼び出される関数に束縛します。</dd>
</dl>
<h3 id="Method_definition_syntax" name="Method_definition_syntax">メソッド定義構文</h3>
<p>ECMAScript 2015 からは、独自のメソッドを、getter と setter に似た、より短い構文で定義することができます。詳細は<a href="/ja/docs/Web/JavaScript/Reference/Functions/Method_definitions">メソッド定義</a>を参照してください。</p>
<pre class="brush: js notranslate">var obj = {
foo() {},
bar() {}
};</pre>
<h2 id="Function_constructor_vs._function_declaration_vs._function_expression" name="Function_constructor_vs._function_declaration_vs._function_expression">コンストラクタか関数宣言か関数式か</h2>
<p>以下のものを比較してみて下さい。</p>
<p><code>Function</code> コンストラクタによって定義され、変数 <code>multiply</code> に代入された関数:</p>
<pre class="brush: js notranslate">var multiply = new Function('x', 'y', 'return x * y');</pre>
<p><code>multiply</code> と命名された関数の <em>関数宣言:</em></p>
<pre class="brush: js notranslate">function multiply(x, y) {
return x * y;
} // ここにセミコロンは必要ありません
</pre>
<p>変数 <code>multiply</code> に代入された、無名関数の<em>関数式:</em></p>
<pre class="brush: js notranslate">var multiply = function(x, y) {
return x * y;
};
</pre>
<p>変数 <code>multiply</code> に代入された、<code>func_name</code> と命名された関数式:</p>
<pre class="brush: js notranslate">var multiply = function func_name(x, y) {
return x * y;
};
</pre>
<h3 id="Differences" name="Differences">相違点</h3>
<p>これらは全ておおよそ同じ働きをしますが、いくつか微妙に異なる点があります。</p>
<p>関数名と関数が代入された変数の間には違いがあります。関数名は変える事ができませんが、関数が代入された変数は再代入する事ができます。関数名は関数本体の内部でのみ使用する事ができます。関数本体の外側でそれを使用しようとするとエラー (その関数名がそれより前に <code>var</code> 文によって宣言されていれば <code>undefined</code> ) になります。例えば、</p>
<pre class="brush: js notranslate">var y = function x() {};
alert(x); // エラーを投げる
</pre>
<p>関数名は <a href="/ja/docs/JavaScript/Reference/Global_Objects/Function/toString" title="ja/JavaScript/Reference/Global_Objects/Function/toString"><code>Function</code> の toString メソッド</a>によってシリアライズしたときにも現れます。</p>
<p>一方、関数が代入された変数はそのスコープ内でのみ有効で、そのスコープは関数が宣言されたスコープを含んでいる事が保証されています。</p>
<p>4 つめの例にあるように、関数名はその関数が代入される変数と違っていても構いません。お互いの間に関連性は有りません。関数宣言は同時にその関数名と同じ名前の変数を作成します。よって、関数式で定義されたものと違って、関数宣言で定義された関数は定義されたスコープ内でその名前によってアクセスできます。</p>
<p><code>new Function</code> によって定義された関数は関数名を持ちません。しかし、JavaScript エンジンの <a href="/ja/docs/SpiderMonkey" title="ja/SpiderMonkey">SpiderMonkey</a> では、その関数をシリアライズされた形式にすると "anonymous" という名前を持っているかのように表示されます。例えば、<code>alert(new Function())</code> はこのように出力されます。</p>
<pre class="brush: js notranslate">function anonymous() {
}
</pre>
<p>この関数は実際には名前を持っていないので、<code>anonymous</code> は関数内部でアクセスできる変数ではありません。例えば、次の文はエラーになります。</p>
<pre class="brush: js notranslate">var foo = new Function("alert(anonymous);");
foo();
</pre>
<p>関数式や <code>Function</code> コンストラクタで定義されたものとは違い、関数宣言で定義された関数は、関数自体が宣言される前に使用する事ができます。例えば、</p>
<pre class="brush: js notranslate">foo(); // FOO! とアラートされる
function foo() {
alert('FOO!');
}
</pre>
<p>関数式で定義された関数は現在のスコープを継承します。つまり、関数がクロージャを形成します。一方、<code>Function</code> コンストラクタで定義された関数は (あらゆる関数が継承する) グローバルスコープ以外はどんなスコープも継承しません。</p>
<pre class="brush: js notranslate">/*
* Declare and initialize a variable 'p' (global)
* and a function 'myFunc' (to change the scope) inside which
* declare a varible with same name 'p' (current) and
* define three functions using three different ways:-
* 1. function declaration
* 2. function expression
* 3. function constructor
* each of which will log 'p'
*/
var p = 5;
function myFunc() {
var p = 9;
function decl() {
console.log(p);
}
var expr = function() {
console.log(p);
};
var cons = new Function('\tconsole.log(p);');
decl();
expr();
cons();
}
myFunc();
/*
* Logs:-
* 9 - for 'decl' by function declaration (current scope)
* 9 - for 'expr' by function expression (current scope)
* 5 - for 'cons' by Function constructor (global scope)
*/
</pre>
<p>関数式と関数宣言で定義された関数は一度しか解析されませんが、<code>Function</code> コンストラクタで定義された関数はそうではありません。つまり、<code>Function</code> コンストラクタに渡された関数本体を表す文字列が、評価されるたびに必ず解析されます。関数式は毎回クロージャを作成しますが、関数本体は再解析されないので、"<code>new Function(...)</code>" よりは関数式の方がまだ高速です。したがって <code>Function</code> コンストラクタはできる限り避けるべきでしょう。</p>
<p>ただし、<code>Function</code> コンストラクタの文字列を解析することで生成された関数内で入れ子にされている関数式や関数宣言は、繰り返し解析されないことに注意してください。例えば:</p>
<pre class="brush: js notranslate">var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
foo(); // 関数本体の文字列で "function() {\n\talert(bar);\n}" の部分は再解析されません</pre>
<p>関数宣言はとても簡単に (しばしば意図せずに) 関数式に変化します。関数宣言は以下のような時には関数宣言ではなくなります。</p>
<ul>
<li>式の一部になった時</li>
<li>関数またはスクリプト自体の「{{ 原語併記("ソース要素", "source element") }}」でなくなった時。「ソース要素」はスクリプトや関数本体の中で入れ子にされていない文の事です。</li>
</ul>
<pre class="brush: js notranslate">var x = 0; // ソース要素
if (x === 0) { // ソース要素
x = 10; // ソース要素ではない
function boo() {} // ソース要素ではない
}
function foo() { // ソース要素
var y = 20; // ソース要素
function bar() {} // ソース要素
while (y === 10) { // ソース要素
function blah() {} // ソース要素ではない
y++; // ソース要素ではない
}
}
</pre>
<h3 id="Examples" name="Examples">例</h3>
<pre class="brush: js notranslate">// 関数宣言
function foo() {}
// 関数式
(function bar() {})
// 関数式
x = function hello() {}
if (x) {
// 関数式
function world() {}
}
// 関数宣言
function a() {
// 関数宣言
function b() {}
if (0) {
// 関数式
function c() {}
}
}
</pre>
<h2 id="Block-level_functions" name="Block-level_functions">ブロックレベル関数</h2>
<p>ES2015 で始まった <a href="/ja/docs/Web/JavaScript/Strict_mode">strict モード</a>では、ブロック内の関数はそのブロックに新しいスコープを形成します。ES2015 より前では、ブロックレベル関数は strict モードでは禁止されています。</p>
<pre class="brush: js notranslate">'use strict';
function f() {
return 1;
}
{
function f() {
return 2;
}
}
f() === 1; // true
// 非 strict モードでは f() === 2
</pre>
<h3 id="Conditionally_defining_a_function" name="Conditionally_defining_a_function">非 strict コードにおけるブロックレベル関数</h3>
<p>一言、使わないでください。</p>
<p>非 strict コードでは、ブロック内の関数宣言は奇妙な動作をします。次の例を見てください。</p>
<pre class="brush: js notranslate">if (shouldDefineZero) {
function zero() { // 危険: 互換性リスク
console.log("This is zero.");
}
}
</pre>
<p>ES2015 では <code>shouldDefineZero</code> が false の場合、このブロックが実行されることはないので、<code>zero</code> は決して定義されないとされています。しかし、これは標準において新しいパーツです。歴史的には、このことは仕様とならないまま残されていました。いくつかのブラウザーでは、ブロックが実行されてもされなくても、<code>zero</code> を定義したでしょう。</p>
<p><a href="/ja/docs/Web/JavaScript/Reference/Strict_mode">strict モード</a>では、ES2015 をサポートする全てのブラウザーは、これを同じように扱います。<code>zero</code> は <code>shouldDefineZero</code> が true の場合のみ定義され、かつ <code>if</code> ブロックのスコープに限られます。</p>
<p>条件付きで関数を定義するより安全な方法は、変数に関数式を代入することです。</p>
<pre class="brush: js notranslate">var zero;
if (shouldDefineZero) {
zero = function() {
console.log("This is zero.");
};
}
</pre>
<h2 id="例">例</h2>
<h3 id="Returning_a_formatted_number" name="Returning_a_formatted_number">フォーマットされた数値を返す</h3>
<p>次の関数は、数値の先頭にゼロを足して固定長にした形で表される文字列を返します。</p>
<pre class="brush: js notranslate">// この関数は先頭にゼロを足して固定長にした文字列を返す
function padZeros(num, totalLen) {
var numStr = num.toString(); // 戻り値を文字列に初期化する
var numZeros = totalLen - numStr.length; // ゼロの数を計算する
for (var i = 1; i <= numZeros; i++) {
numStr = "0" + numStr;
}
return numStr;
}
</pre>
<p>次の文で padZeros 関数を呼び出します。</p>
<pre class="brush: js notranslate">var result;
result = padZeros(42,4); // "0042" を返す
result = padZeros(42,2); // "42" を返す
result = padZeros(5,4); // "0005" を返す
</pre>
<h3 id="Determining_whether_a_function_exists" name="Determining_whether_a_function_exists">関数が存在するかどうか確認する</h3>
<p><code>typeof</code> 演算子を使うと関数が存在するかどうかを確かめる事ができます。次の例では、<code>window</code> オブジェクトが <code>noFunc</code> という関数のプロパティを持つかどうかを確かめるためのテストが行われます。もし持っていたら、それが使われます。そうでなければ、他の行動が取られます。</p>
<pre class="brush: js notranslate"> if ('function' == typeof window.noFunc) {
// noFunc() を使う
} else {
// 何か他のことをする
}
</pre>
<p><code>if</code> のテストの中で、<code>noFunc</code> への参照が使われているのに注目してください。関数名の後に括弧 "()" が無いので、実際の関数は呼ばれません。</p>
<h2 id="Specifications" name="Specifications">仕様</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">仕様書</th>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>
<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、<a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div>
<p>{{Compat("javascript.functions")}}</p>
<h2 id="See_also" name="See_also">関連情報</h2>
<ul>
<li>{{jsxref("Statements/function", "function 文")}}</li>
<li>{{jsxref("Operators/function", "function 演算子")}}</li>
<li>{{jsxref("Statements/function*", "function* 文")}}</li>
<li>{{jsxref("Operators/function*", "function* 演算子")}}</li>
<li>{{jsxref("Function")}}</li>
<li>{{jsxref("GeneratorFunction", "ジェネレーター関数")}}</li>
<li>{{jsxref("Functions/Arrow_functions", "アロー関数")}}</li>
<li>{{jsxref("Functions/Default_parameters", "デフォルト引数")}}</li>
<li>{{jsxref("Functions/rest_parameters", "Rest parameters")}}</li>
<li>{{jsxref("Functions/arguments", "arguments オブジェクト")}}</li>
<li>{{jsxref("Functions/get", "getter")}}</li>
<li>{{jsxref("Functions/set", "setter")}}</li>
<li>{{jsxref("Functions/Method_definitions", "メソッド定義")}}</li>
<li><a href="/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope">関数と関数スコープ</a></li>
</ul>
|