From baece57aa45a42c88669937a76f0d42f7136780c Mon Sep 17 00:00:00 2001
From: Masahiro FUJIMOTO 関数のデフォルト引数 は、関数に値が渡されない場合や このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、https://github.com/mdn/interactive-examples をクローンしてプルリクエストを送信してください。 JavaScript では、関数の引数は、指定しなければ {{jsxref("undefined")}} になります。しかし、別な既定値を設定すると有用な場合がよくあります。そのような場合に、デフォルト引数が役立ちます。 以前は、既定値を設定するための一般的な方法は、関数の本体で引数の値を検査し、 次の例では、 こうなることを防ぐためには、2行目で使われているように、 ES2015 のデフォルト引数を用いると、関数本体内のチェックはもはや必要なくなります。関数の先頭で この例の 2番目の呼び出しでは、第1引数で明示的に ( デフォルト引数は呼び出し時に評価されるので、Python などと異なり、関数が呼ばれる度に新しいオブジェクトが生成されます。 これは、関数と変数にも適用されます。 前に (左側で) 定義された引数は、その後のデフォルト引数で利用することができます。 この機能はこの、いくつもの極端な例を扱うデモに近いかもしれません。 関数の本体の中で宣言された関数は、外側の関数のデフォルト引数の中で参照することができません。これを行おうとすると、{{jsxref("ReferenceError")}} が発生します。 デフォルト引数は、常に最初に実行され、関数本体内の関数宣言は、その後に評価されるからです。 引数は左から右に設定され、後の引数に既定値がなくてもデフォルト引数を上書きします。 既定値の代入を、{{jsxref("Operators/Destructuring_assignment", "分割代入", "", 1)}}表記で行うことができます。 {{Compat("javascript.functions.default_parameters")}}undefined
が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。構文
-
-function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
- 文
-}
-
-
-解説
-
-undefined
であった場合に値を代入することでした。b
の値を指定せずに multiply
を呼び出した場合、a * b
を評価するときに b
の値が undefined
となり、multiply
は NaN
を返します。function multiply(a, b) {
- return a * b
-}
-
-multiply(5, 2) // 10
-multiply(5) // NaN !
-
-
-multiply
が 1 つだけの引数で呼び出された場合に b
を 1
に設定します。function multiply(a, b) {
- b = (typeof b !== 'undefined') ? b : 1
- return a * b
-}
-
-multiply(5, 2) // 10
-multiply(5) // 5
-
-
-1
を b
の既定値として設定するだけです。function multiply(a, b = 1) {
- return a * b
-}
-
-multiply(5, 2) // 10
-multiply(5) // 5
-multiply(5, undefined) // 5
-
-
-例
-
-
-
-undefined
とその他の falsy な値を渡した場合null
やその他の {{glossary("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 に設定)
-
-
-呼び出し時の評価
-
-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 が発生します。
-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
-
-仕様書
-
-
-
-
-
-
-
-
-
- 仕様書
-
-
-
-{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}
- ブラウザーの互換性
-
-関連情報
-
-
diff --git a/files/ja/web/javascript/reference/functions/default_parameters/index.md b/files/ja/web/javascript/reference/functions/default_parameters/index.md
new file mode 100644
index 0000000000..4d0833cd3b
--- /dev/null
+++ b/files/ja/web/javascript/reference/functions/default_parameters/index.md
@@ -0,0 +1,229 @@
+---
+title: デフォルト引数
+slug: Web/JavaScript/Reference/Functions/Default_parameters
+tags:
+ - ECMAScript 2015
+ - Functions
+ - JavaScript
+ - Language feature
+ - 言語機能
+ - 関数
+browser-compat: javascript.functions.default_parameters
+translation_of: Web/JavaScript/Reference/Functions/Default_parameters
+---
+{{jsSidebar("Functions")}}
+
+**関数のデフォルト引数**は、関数に値が渡されない場合や `undefined` が渡された場合に、デフォルト値で初期化される形式上の引数を指定することができます。
+
+{{EmbedInteractiveExample("pages/js/functions-default.html")}}
+
+## 構文
+
+```js
+function fnName(param1 = defaultValue1, ..., paramN = defaultValueN) { ... }
+```
+
+## 解説
+
+JavaScript では、関数の引数は、指定しなければ {{jsxref("undefined")}} になります。しかし、別な既定値を設定すると有用な場合がよくあります。そのような場合に、デフォルト引数が役立ちます。
+
+以前は、既定値を設定するための一般的な方法は、関数の本体で引数の値を検査し、`undefined` であった場合に値を代入することでした。
+
+次の例では、`b` の値を指定せずに `multiply` を呼び出した場合、`a` * `b` を評価するときに `b` の値が `undefined` となり、`multiply` は `NaN` を返します。
function test(num = 1) { + console.log(typeof num) +} + +test() // 'number' (num は 1 に設定) +test(undefined) // 'number' (こちらも num は 1 に設定) + +// 他の偽値での検査 +test('') // 'string' (num は '' に設定) +test(null) // 'object' (num は null に設定) ++ +### 呼び出し時の評価 + +デフォルト引数は*呼び出し時*に評価されるので、(例えば) Python などと異なり、関数が呼ばれる度に新しいオブジェクトが生成されます。 + +```js +function append(value, array = []) { + array.push(value) + return array +} + +append(1) // [1] +append(2) // [1, 2] ではなく [2] +``` + +これは、関数と変数にも適用されます。 + +```js +function callSomething(thing = something()) { + return thing +} + +let numberOfTimesCalled = 0 +function something() { + numberOfTimesCalled += 1 + return numberOfTimesCalled +} + +callSomething() // 1 +callSomething() // 2 +``` + +### 前の引数を後のデフォルト引数で利用可能 + +前に (左側で) 定義された引数は、その後のデフォルト引数で利用することができます。 + +```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!"] +``` + +この機能はこの、いくつもの極端な例を扱うデモに近いかもしれません。 + +```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, "=^_^="] +``` + +### スコープの影響 + +デフォルト引数が 1 つ以上定義された場合、引数リスト内の識別子のみに対する[第二のスコープ](https://tc39.es/ecma262/#sec-functiondeclarationinstantiation) (Environment Record) が生成されます。このスコープは関数本体のために生成されたスコープの親になります。 + +すなわち、関数の本体で宣言された関数や変数は、デフォルト値の引数初期化子から参照することができません。これを行おうとすると、実行時に {{jsxref("ReferenceError")}} の例外が発生します。 + +また、関数の本体内で `var` を使用して宣言した変数は、同じ名前の引数をマスクするので、通常の `var` 宣言の重複に効果がないのとは異なります。 + +次の関数では、デフォルト引数が関数本体の子スコープにアクセスできないため、呼び出されると `ReferenceError` が発生します。T + +```js example-bad +function f(a = go()) { // `f` を呼び出すと `ReferenceError` が発生する。 + function go() { return ':P' } +} +``` + +...そしてこの関数は、変数 `var a` が (引数リストに作成された親スコープではなく) 関数本体に作成されたスコープの最上部にのみ巻き上げられているため、 `undefined` と表示されます。 + +```js example-bad +function f(a, b = () => console.log(a)) { + var a = 1 + b() // `undefined` と表示。デフォルト引数の値は独自のスコープにあるため +} +``` + +### デフォルト引数の後の既定値なしの引数 + +引数は左から右に設定され、後の引数に既定値がなくてもデフォルト引数を上書きします。 + +```js +function f(x = 1, y) { + return [x, y] +} + +f() // [1, undefined] +f(2) // [2, undefined] +``` + +### 既定値のある分割代入の引数 + +既定値の代入を、{{jsxref("Operators/Destructuring_assignment", "分割代入", "", 1)}}表記で行うことができます。 + +```js +function f([x, y] = [1, 2], {z: z} = {z: 3}) { + return x + y + z +} + +f() // 6 +``` + +## 仕様書 + +{{Specifications}} + +## ブラウザーの互換性 + +{{Compat}} + +## 関連情報 + +- [ecmascript.org における元の提案](http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values) -- cgit v1.2.3-54-g00ecf