関数のデフォルト引数 は、関数に値が渡されない場合や undefined
が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。
構文
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) { statements }
説明
JavaScriptでは、関数の引数は、指定しなければ
になります。しかし、異なるデフォルト値を設定できると有用な場面があるでしょう。そのような場合に、デフォルト引数が役立ちます。undefined
以前のデフォルト値を設定するための一般的な方法は、関数の本体で引数値をテストし、undefined
の場合に値を代入することでした。
次の例では、multiply
が呼び出されたときにb
に値が指定されていないと、a * b
を評価するときにb
の値は未定義になり、multiply
はNaN
を返します。
function multiply(a, b) {
return a * b;
}
multiply(5, 2); // 10
multiply(5); // NaN !
しかしながら、これは、次の例の 2 行目で対処することができます。1つの引数だけでmultiply
が呼び出された場合、b
は1
に設定されます。
function multiply(a, b) {
var b = typeof b !== 'undefined' ? b : 1;
return a*b;
}
multiply(5, 2); // 10
multiply(5); // 5
ES2015 のデフォルト引数を用いると、関数本体内のチェックはもはや必要ありません。関数先頭で、b
のデフォルト値として、単に 1
を設定するだけです:
function multiply(a, b = 1) {
return a*b;
}
multiply(5, 2); // 10
multiply(5); // 5
例
undefined
を渡す
2 番目の呼び出しで、呼び出し時の第二引数に明示的に undefined
(null
ではない) が設定されても、color
引数の値はデフォルト値になります。
function setBackgroundColor(element, color = 'rosybrown') { element.style.backgroundColor = color; } setBackgroundColor(someDiv); // color に 'rosybrown' が設定される setBackgroundColor(someDiv, undefined); // これも color に 'rosybrown' が設定される setBackgroundColor(someDiv, 'blue'); // color に 'blue' が設定される
呼び出し時の評価
デフォルト引数は呼び出し時に評価されるので、例えば Python と違い、関数が呼ばれる度に新しいオブジェクトが生成されます。
function append(value, array = []) { array.push(value); return array; } append(1); //[1] append(2); //[1, 2] ではなく [2]
これは、関数と変数にも適用されます:
function callSomething(thing = something()) { return thing } function something(){ return "sth"; } callSomething(); //sth
デフォルト引数は後続のデフォルト引数で再利用可能
すでに出現した引数は、その後に続くデフォルト引数でも利用できます:
function singularAutoPlural(singular, plural = singular+"s", rallyingCry = plural + " ATTACK!!!") { return [singular, plural, rallyingCry ]; } //["Gecko","Geckos", "Geckos ATTACK!!!"] singularAutoPlural("Gecko"); //["Fox","Foxes", "Foxes ATTACK!!!"] singularAutoPlural("Fox","Foxes"); //["Deer", "Deer", "Deer ... change."] singularAutoPlural("Deer", "Deer", "Deer peaceably and respectfully petition the government for positive change.")
この機能は、隣接したデフォルト引数に続けて再利用することができます。次の例は、この極端な使い方を示します。
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, "=^_^="]
関数本体の内部で定義された関数
Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30) で導入されました。関数本体内で宣言された関数は、デフォルト引数の内部で参照できないため、ReferenceError
を投げます (現在、SpiderMonkey では TypeError
です。バグ 1022967 参照)。デフォルト引数は、常に最初に実行され、関数本体内の関数宣言は、その後に評価されます。
// Doesn't work! Throws ReferenceError. function f(a = go()) { function go(){return ":P"} }
デフォルト引数後のデフォルト値なしの引数
Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) 以前で、次のコードの結果は SyntaxError
になります。これは、バグ 777060 で修正され、最新バージョンでは期待通り動作します:
function f(x=1, y) { return [x, y]; } f(); // [1, undefined]
構造化代入のデフォルト引数
分割代入 記法でデフォルト値を代入できます:
function f([x, y] = [1, 2], {z: z} = {z: 3}) { return x + y + z; } f(); // 6
仕様
仕様書 | 策定状況 | 備考 |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) Function Definitions の定義 |
標準 | 初期定義。 |
ECMAScript Latest Draft (ECMA-262) Function Definitions の定義 |
ドラフト |
ブラウザ実装状況
デスクトップ | モバイル | サーバー | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Default parameters | Chrome 完全対応 49 | Edge 完全対応 14 | Firefox 完全対応 15 | IE 未対応 なし | Opera 完全対応 36 | Safari 完全対応 10 | WebView Android 完全対応 49 | Chrome Android 完全対応 49 | Firefox Android 完全対応 15 | Opera Android 完全対応 36 | Safari iOS 完全対応 10 | Samsung Internet Android 完全対応 5.0 | nodejs 完全対応 6.0.0 |
Destructured parameter with default value assignment | Chrome 完全対応 49 | Edge 完全対応 14 | Firefox 完全対応 41 | IE 未対応 なし | Opera 完全対応 36 | Safari ? | WebView Android 完全対応 49 | Chrome Android 完全対応 49 | Firefox Android 完全対応 41 | Opera Android ? | Safari iOS ? | Samsung Internet Android 完全対応 5.0 | nodejs 完全対応 あり |
Parameters without defaults after default parameters | Chrome 完全対応 49 | Edge 完全対応 14 | Firefox 完全対応 26 | IE 未対応 なし | Opera 完全対応 36 | Safari 完全対応 10 | WebView Android 完全対応 49 | Chrome Android 完全対応 49 | Firefox Android 完全対応 26 | Opera Android 完全対応 36 | Safari iOS 完全対応 10 | Samsung Internet Android 完全対応 5.0 | nodejs 完全対応 あり |
凡例
- 完全対応
- 完全対応
- 未対応
- 未対応
- 実装状況不明
- 実装状況不明