aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/web/javascript/reference/functions/default_parameters/index.html
blob: 73bc901464f28815c9f438efc258c2f7df88496e (plain)
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
---
title: 預設參數( Default parameters )
slug: Web/JavaScript/Reference/Functions/Default_parameters
translation_of: Web/JavaScript/Reference/Functions/Default_parameters
---
<div>{{jsSidebar("Functions")}}</div>

<p><strong>函式預設參數 </strong>允許沒有值傳入或是傳入值為 <code>undefined 的情況下,參數能以指定的預設值初始化。</code></p>

<h2 id="語法">語法</h2>

<pre class="syntaxbox">function [<em>name</em>]([<em>param1</em>[ = defaultValue1 ][, ..., <em>paramN</em>[ = defaultValueN ]]]) {
   <em>要執行的程序</em>
}
</pre>

<h2 id="說明">說明</h2>

<p>在 JavaScript 中,函式的參數預設值都為 <code>{{jsxref("undefined")}} 。然而,指定不同的預設值可能在一些場景很有用。這也是函式參數預設值可以幫上忙的地方。</code></p>

<p>以往設定預設值有個普遍方法:在函式的內容裡檢查傳入參數是否為 <code>undefined ,如果是的話,爲他指定一個值。如下列範例,若函式被呼叫時,並沒有提供 b 的值,它的值就會是 undefined,在計算 a*b 時,以及呼叫 multiply 時,就會回傳 NaN。然而這在範例的第二行被阻止了:</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, 1); // 5
multiply(5);    // 5
</pre>

<p>有了 ES2015 的預設參數,再也不用於函式進行檢查了,現在只要簡單的在函式的起始處為 b 指定 1 的值:</p>

<pre class="brush: js">function multiply(a, b = 1) {
  return a * b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5
</pre>

<h2 id="範例">範例</h2>

<h3 id="傳入_undefined">傳入 <code>undefined</code></h3>

<p>這邊第二段函式呼叫中,僅管第二個傳入參數在呼叫時明確地指定為undefined(雖不是null),其顏色參數的值是預設值(rosybrown)。</p>

<pre class="brush: js">function setBackgroundColor(element, color = 'rosybrown') {
  element.style.backgroundColor = color;
}

setBackgroundColor(someDiv);            // color set to 'rosybrown'
setBackgroundColor(someDiv, undefined); // color set to 'rosybrown' too
setBackgroundColor(someDiv, 'blue');    // color set to 'blue'
</pre>

<h3 id="呼叫時賦予值">呼叫時賦予值</h3>

<p>跟Python等語言不同的地方是,先前預設的代數值會拿來進行函式內的程序,也因此在函式呼叫的時候,會建立新物件。</p>

<pre class="brush: js">function append(value, array = []) {
  array.push(value);
  return array;
}

append(1); //[1]
append(2); //[2], 而非 [1, 2]
</pre>

<p>諸如此類的做法,也適用在函式和變量。</p>

<pre class="brush: js">function callSomething(thing = something()) {
 return thing;
}

function something() {
  return 'sth';
}

callSomething();  //sth</pre>

<h3 id="預設的參數中,先設定的可提供之後設定的使用">預設的參數中,先設定的可提供之後設定的使用</h3>

<p>先前有碰到的參數,後來的即可使用。</p>

<pre class="brush: js">function singularAutoPlural(singular, plural = singular + '們',
                            rallyingCry = plural + ',進攻啊!!!') {
  return [singular, plural, rallyingCry];
}

//["壁虎","壁虎們", "壁虎,進攻啊!!!"]
singularAutoPlural('壁虎');

//["狐狸","火紅的狐狸們", "火紅的狐狸們,進攻啊!!!"]
singularAutoPlural('狐狸', '火紅的狐狸們');

//["鹿兒", "鹿兒們", "鹿兒們 ... 有所好轉"]
singularAutoPlural('鹿兒', '鹿兒們', '鹿兒們平心靜氣的 \
   向政府請願,希望事情有所好轉。');
</pre>

<p>This functionality is approximated in a straight forward fashion and demonstrates how many edge cases are handled.</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="函式內再定義函式">函式內再定義函式</h3>

<p>Introduced in Gecko 33 {{geckoRelease(33)}}. Functions declared in the function body cannot be referred inside default parameters and throw a {{jsxref("ReferenceError")}} (currently a {{jsxref("TypeError")}} in SpiderMonkey, see {{bug(1022967)}}). Default parameters are always executed first, function declarations inside the function body evaluate afterwards.</p>

<pre class="brush: js">// 行不通的! 最後會丟出 ReferenceError。
function f(a = go()) {
  function go() { return ':P'; }
}
</pre>

<h3 id="Parameters_without_defaults_after_default_parameters">Parameters without defaults after default parameters</h3>

<p>Prior to Gecko 26 {{geckoRelease(26)}}, the following code resulted in a {{jsxref("SyntaxError")}}. This has been fixed in {{bug(777060)}} and works as expected in later versions. Parameters are still set left-to-right, overwriting default parameters even if there are later parameters without defaults.</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">Destructured parameter with default value assignment</h3>

<p>You can use default value assignment with the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destructuring assignment</a> notation:</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">Specifications</h2>

{{Specifications}}

<h2 id="瀏覽器的兼容性">瀏覽器的兼容性</h2>

{{Compat}}

<h2 id="要不要也看看">要不要也看看</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>