関数のデフォルト引数 は、関数に値が渡されない場合や undefined
が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、https://github.com/mdn/interactive-examples をクローンしてプルリクエストを送信してください。
構文
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) { 文 }
解説
JavaScript では、関数の引数は、指定しなければ undefined
になります。しかし、別な既定値を設定すると有用な場合がよくあります。そのような場合に、デフォルト引数が役立ちます。
以前は、既定値を設定するための一般的な方法は、関数の本体で引数の値を検査し、undefined
であった場合に値を代入することでした。
次の例では、b
の値を指定せずに multiply
を呼び出した場合、a * b
を評価するときに b
の値が undefined
となり、multiply
は NaN
を返します。
function multiply(a, b) {
return a * b
}
multiply(5, 2) // 10
multiply(5) // NaN !
こうなることを防ぐためには、2行目で使われているように、multiply
が 1 つだけの引数で呼び出された場合に b
を 1
に設定します。
function multiply(a, b) {
b = (typeof b !== 'undefined') ? b : 1
return a * b
}
multiply(5, 2) // 10
multiply(5) // 5
ES2015 のデフォルト引数を用いると、関数本体内のチェックはもはや必要なくなります。関数の先頭で 1
を b
の既定値として設定するだけです。
function multiply(a, b = 1) {
return a * b
}
multiply(5, 2) // 10
multiply(5) // 5
multiply(5, undefined) // 5
例
undefined
とその他の falsy な値を渡した場合
この例の 2番目の呼び出しでは、第1引数で明示的に (null
やその他の falsy な値ではなく) undefined
を設定していても、num
引数の値は既定値のままになります
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 に設定)
呼び出し時の評価
デフォルト引数は呼び出し時に評価されるので、Python などと異なり、関数が呼ばれる度に新しいオブジェクトが生成されます。
function append(value, array = []) {
array.push(value)
return array
}
append(1) //[1]
append(2) //[1, 2] ではなく [2]
これは、関数と変数にも適用されます。
function callSomething(thing = something()) {
return thing
}
let numberOfTimesCalled = 0
function something() {
numberOfTimesCalled += 1
return numberOfTimesCalled
}
callSomething() // 1
callSomething() // 2
前の引数を後のデフォルト引数で利用可能
前に (左側で) 定義された引数は、その後のデフォルト引数で利用することができます。
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!"]
この機能はこの、いくつもの極端な例を扱うデモに近いかもしれません。
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, "=^_^="]
関数本体の内部で定義された関数
関数の本体の中で宣言された関数は、外側の関数のデフォルト引数の中で参照することができません。これを行おうとすると、ReferenceError
が発生します。
デフォルト引数は、常に最初に実行され、関数本体内の関数宣言は、その後に評価されるからです。
// 動作しません。ReferenceError が発生します。
function f(a = go()) {
function go() { return ':P' }
}
デフォルト引数の後の既定値なしの引数
引数は左から右に設定され、後の引数に既定値がなくてもデフォルト引数を上書きします。
function f(x = 1, y) {
return [x, y]
}
f() // [1, undefined]
f(2) // [2, undefined]
既定値のある分割代入の引数
既定値の代入を、分割代入表記で行うことができます。
function f([x, y] = [1, 2], {z: z} = {z: 3}) {
return x + y + z
}
f() // 6
仕様書
ブラウザーの互換性
BCD tables only load in the browser