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
|
---
title: デフォルト引数
slug: Web/JavaScript/Reference/Functions/Default_parameters
tags:
- ECMAScript 2015
- Functions
- JavaScript
- Language feature
- 言語機能
- 関数
translation_of: Web/JavaScript/Reference/Functions/Default_parameters
---
<div>{{jsSidebar("Functions")}}</div>
<p><span class="seoSummary"><strong>関数のデフォルト引数</strong> は、関数に値が渡されない場合や <code>undefined</code> が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。</span></p>
<div>{{EmbedInteractiveExample("pages/js/functions-default.html")}}</div>
<p class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、<a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</p>
<h2 id="Syntax" name="Syntax">構文</h2>
<pre class="syntaxbox">function [<var>name</var>]([<var>param1</var>[ = <var>defaultValue1</var> ][, ..., <var>paramN</var>[ = <var>defaultValueN</var> ]]]) {
<var>文</var>
}
</pre>
<h2 id="Description" name="Description">解説</h2>
<p>JavaScript では、関数の引数は、指定しなければ {{jsxref("undefined")}} になります。しかし、別な既定値を設定すると有用な場合がよくあります。そのような場合に、デフォルト引数が役立ちます。</p>
<p>以前は、既定値を設定するための一般的な方法は、関数の本体で引数の値を検査し、<code>undefined</code> であった場合に値を代入することでした。</p>
<p>次の例では、<code><var>b</var></code> の値を指定せずに <code>multiply</code> を呼び出した場合、<code><var>a</var> * <var>b</var></code> を評価するときに <code><var>b</var></code> の値が <code>undefined</code> となり、<code>multiply</code> は <code>NaN</code> を返します。</p>
<pre class="brush: js">function multiply(a, b) {
return a * b
}
multiply(5, 2) // 10
multiply(5) // NaN !
</pre>
<p>こうなることを防ぐためには、2行目で使われているように、<code>multiply</code> が 1 つだけの引数で呼び出された場合に <code><var>b</var></code> を <code>1</code> に設定します。</p>
<pre class="brush: js">function multiply(a, b) {
b = (typeof b !== 'undefined') ? b : 1
return a * b
}
multiply(5, 2) // 10
multiply(5) // 5
</pre>
<p>ES2015 のデフォルト引数を用いると、関数本体内のチェックはもはや必要なくなります。関数の先頭で <code>1</code> を <code><var>b</var></code> の既定値として設定するだけです。</p>
<pre class="brush: js">function multiply(a, b = 1) {
return a * b
}
multiply(5, 2) // 10
multiply(5) // 5
multiply(5, undefined) // 5
</pre>
<h2 id="Examples" name="Examples">例</h2>
<h3 id="undefined_とその他の_falsy_な値を渡した場合"><code>undefined</code> とその他の falsy な値を渡した場合</h3>
<p>この例の 2番目の呼び出しでは、第1引数で明示的に (<code>null</code> やその他の {{glossary("falsy")}} な値ではなく) <code>undefined</code> を設定していても、<code><var>num</var></code> 引数の値は既定値のままになります</p>
<pre class="brush: js">function test(num = 1) {
console.log(typeof num)
}
test() // 'number' (num は 1 に設定)
test(undefined) // 'number' (こちらも num は 1 に設定)
// 他の falsy な値での検査
test('') // 'string' (num は '' に設定)
test(null) // 'object' (num は null に設定)
</pre>
<h3 id="Evaluated_at_call_time" name="Evaluated_at_call_time">呼び出し時の評価</h3>
<p>デフォルト引数は<em>呼び出し時</em>に評価されるので、Python などと異なり、関数が呼ばれる度に新しいオブジェクトが生成されます。</p>
<pre class="brush: js">function append(value, array = []) {
array.push(value)
return array
}
append(1) //[1]
append(2) //[1, 2] ではなく [2]
</pre>
<p>これは、関数と変数にも適用されます。</p>
<pre class="brush: js">function callSomething(thing = something()) {
return thing
}
let numberOfTimesCalled = 0
function something() {
numberOfTimesCalled += 1
return numberOfTimesCalled
}
callSomething() // 1
callSomething() // 2
</pre>
<h3 id="Earlier_parameters_are_available_to_later_default_parameters" name="Earlier_parameters_are_available_to_later_default_parameters">前の引数を後のデフォルト引数で利用可能</h3>
<p>前に (左側で) 定義された引数は、その後のデフォルト引数で利用することができます。</p>
<pre class="brush: js">function greet(name, greeting, message = greeting + ' ' + name) {
return [name, greeting, message]
}
greet('David', 'Hi') // ["David", "Hi", "Hi David"]
greet('David', 'Hi', 'Happy Birthday!') // ["David", "Hi", "Happy Birthday!"]
</pre>
<p>この機能はこの、いくつもの極端な例を扱うデモに近いかもしれません。</p>
<pre class="brush: js">function go() {
return ':P'
}
function withDefaults(a, b = 5, c = b, d = go(), e = this,
f = arguments, g = this.value) {
return [a, b, c, d, e, f, g]
}
function withoutDefaults(a, b, c, d, e, f, g) {
switch (arguments.length) {
case 0:
a;
case 1:
b = 5;
case 2:
c = b;
case 3:
d = go();
case 4:
e = this;
case 5:
f = arguments;
case 6:
g = this.value;
default:
}
return [a, b, c, d, e, f, g];
}
withDefaults.call({value: '=^_^='});
// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
withoutDefaults.call({value: '=^_^='});
// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
</pre>
<h3 id="Functions_defined_inside_function_body" name="Functions_defined_inside_function_body">関数本体の内部で定義された関数</h3>
<p>関数の本体の中で宣言された関数は、外側の関数のデフォルト引数の中で参照することができません。これを行おうとすると、{{jsxref("ReferenceError")}} が発生します。</p>
<p>デフォルト引数は、常に最初に実行され、関数本体内の関数宣言は、その後に評価されるからです。</p>
<pre class="brush: js">// 動作しません。ReferenceError が発生します。
function f(a = go()) {
function go() { return ':P' }
}
</pre>
<h3 id="Parameters_without_defaults_after_default_parameters" name="Parameters_without_defaults_after_default_parameters">デフォルト引数の後の既定値なしの引数</h3>
<p>引数は左から右に設定され、後の引数に既定値がなくてもデフォルト引数を上書きします。</p>
<pre class="brush: js">function f(x = 1, y) {
return [x, y]
}
f() // [1, undefined]
f(2) // [2, undefined]
</pre>
<h3 id="Destructured_parameter_with_default_value_assignment" name="Destructured_parameter_with_default_value_assignment">既定値のある分割代入の引数</h3>
<p>既定値の代入を、{{jsxref("Operators/Destructuring_assignment", "分割代入", "", 1)}}表記で行うことができます。</p>
<pre class="brush: js">function f([x, y] = [1, 2], {z: z} = {z: 3}) {
return x + y + z
}
f() // 6</pre>
<h2 id="Specifications" name="Specifications">仕様書</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">仕様書</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>
<div>
<p>{{Compat("javascript.functions.default_parameters")}}</p>
</div>
<h2 id="See_also" name="See_also">関連情報</h2>
<ul>
<li><a class="external" href="http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values" rel="external" title="http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values">Original proposal at ecmascript.org</a></li>
</ul>
|