関数のデフォルト引数 は、関数に値が渡されない場合や undefined
が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。
構文
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) { statements }
説明
JavaScriptでは、関数の引数は、指定しなければ undefined
になります。しかし、異なるデフォルト値を設定できると有用な場面があるでしょう。そのような場合に、デフォルト引数が役立ちます。
以前のデフォルト値を設定するための一般的な方法は、関数の本体で引数値をテストし、undefined
の場合に値を代入することでした。呼び出し側で b
の値が与えられていない次のような例では、a*b
を評価する時、b
の値が undefined
になり、multiply
を呼び出すと NaN
を返します。しかしながら、これは、この例の 2 行目で対処されています:
function multiply(a, b) { var b = typeof b !== 'undefined' ? b : 1; return a*b; } multiply(5); // 5
ES6 のデフォルト引数を用いると、関数本体内のチェックはもはや必要ありません。関数先頭で、b
のデフォルト値として、単に 1
を設定するだけです:
function multiply(a, b = 1) { return a*b; } 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 2017 Draft (ECMA-262) Function Definitions の定義 |
ドラフト |
ブラウザ実装状況
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
基本サポート | 49 | 15.0 (15.0) | 未サポート | 未サポート | 未サポート |
デフォルト引数後のデフォルト値なしの引数 | 49 | 26.0 (26.0) | ? | ? | ? |
構造化代入のデフォルト引数 | 49 | 41.0 (41.0) | ? | ? | ? |
機能 | Android | Android Webview | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
---|---|---|---|---|---|---|---|
基本サポート | 未サポート | 49 | 15.0 (15.0) | 未サポート | 未サポート | 未サポート | 49 |
デフォルト引数後のデフォルト値なしの引数 | 未サポート | 49 | 26.0 (26.0) | ? | ? | ? | 49 |
構造化代入のデフォルト引数 | 未サポート | ? | 41.0 (41.0) | ? | ? | ? | ? |