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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
|
---
title: Array
slug: Web/JavaScript/Reference/Global_Objects/Array
tags:
- Array
- JavaScript
- NeedsTranslation
- TopicStub
- 陣列
translation_of: Web/JavaScript/Reference/Global_Objects/Array
---
<div>{{JSRef}}</div>
<p>JavaScript 中的 <strong><code>Array</code></strong> 全域物件被用於建構陣列;陣列為高階(high-level)、似列表(list-like)的物件。陣列在Javascript 裡面並沒有固定的長度與型別。由於陣列的長度可以隨時被改變,所以並不能保證陣列的密度。這取決於開發者如何使用陣列。一般來說,這是個非常方便的特性,但如果這並不適用於你的開發工作,你也許會考慮使用型別陣列。</p>
<p><strong>建立陣列</strong></p>
<pre class="brush: js">var fruits = ['Apple', 'Banana'];
console.log(fruits.length);
// 2
</pre>
<p><strong>(透過索引)取得陣列項目</strong></p>
<pre class="brush: js">var first = fruits[0];
// Apple
var last = fruits[fruits.length - 1];
// Banana
</pre>
<p><strong>迭代陣列</strong></p>
<pre class="brush: js">fruits.forEach(function(item, index, array) {
console.log(item, index);
});
// Apple 0
// Banana 1
</pre>
<p><strong>加入項目至陣列末端</strong></p>
<pre class="brush: js">var newLength = fruits.push('Orange');
// ["Apple", "Banana", "Orange"]
</pre>
<p><strong>移除陣列末端項目</strong></p>
<pre class="brush: js">var last = fruits.pop(); // 移除 <code>(</code>最末端的<code>) </code>Orange
// ["Apple", "Banana"];
</pre>
<p><strong>移除陣列前端項目</strong></p>
<pre class="brush: js"><code>var first = fruits.shift(); // 移除 (最前端的) Apple
// ["Banana"];</code></pre>
<p><strong>加入項目至陣列前端</strong></p>
<pre class="brush: js">var newLength = fruits.unshift('Strawberry') // 加到陣列前端
// ["Strawberry", "Banana"];
</pre>
<p><strong>在陣列中尋找項目的索引</strong></p>
<pre class="brush: js">fruits.push('Mango');
// ["Strawberry", "Banana", "Mango"]
var pos = fruits.indexOf('Banana');
// 1
</pre>
<p><strong>移除指定索引位置的項目</strong></p>
<pre class="brush: js">var removedItem = fruits.splice(pos, 1); // 移除 pos 起的 1 個項目
// ["Strawberry", "Mango"]</pre>
<p><strong>移除指定索引位置起的多個項目</strong></p>
<pre class="brush: js">var vegetables = ['Cabbage', 'Turnip', 'Radish', 'Carrot'];
console.log(vegetables);
// ["Cabbage", "Turnip", "Radish", "Carrot"]
var pos = 1, n = 2;
var removedItems = vegetables.splice(pos, n);
// 這就是移除項目的方式,
// n 表示從該位置 (pos) 開始,一直到陣列的尾端有多少項目需要移除
console.log(vegetables);
// ["Cabbage", "Carrot"] (原始的陣列被改變)
console.log(removedItems);
// ["Turnip", "Radish"]</pre>
<p><strong>複製陣列</strong></p>
<pre class="brush: js">var shallowCopy = fruits.slice(); // 這就是複製陣列的方式
// ["Strawberry", "<code>Mango</code>"]
</pre>
<h2 id="Syntax" name="Syntax">語法</h2>
<pre class="syntaxbox">[<var>element0</var>, <var>element1</var>, ..., <var>elementN</var>]
new Array(<var>element0</var>, <var>element1</var>[, ...[, <var>elementN</var>]])
new Array(<var>arrayLength</var>)</pre>
<h3 id="參數">參數</h3>
<dl>
<dt><code>element<em>N</em></code></dt>
<dd>除了只傳遞一個參數給 <code>Array</code> 構造函數,且該參數為一個數字的情況(詳見下方的 arrayLength 參數),JavaScript 陣列會以傳入的元素進行初始化。</dd>
<dd>請注意,這種特殊情況僅適用於以 <code>Array </code>構造函數建立的 JavaScript 陣列,而不適用於以括號語法建立的陣列常值(Array Literals)。</dd>
<dt><code>arrayLength</code></dt>
<dd>如果傳遞給 <code>Array</code> 構造函數的唯一參數是 0 和 2<sup>32</sup>-1(含)之間的整數,將回傳一個新的 JavaScript 陣列,其長度被設定為這個數字。如果參數是任何其他數值,將拋出 {{jsxref("RangeError")}} 異常。</dd>
</dl>
<h2 id="Description" name="Description">說明</h2>
<p>Array(「陣列」)是類似列表(list)的物件(Object),它們的原型(Prototype)擁有方法(methods)來執行遍歷和變異操作。JavaScript 陣列的長度(元素數量),以及其元素的類型都不是固定的。取決於工程師如何選擇使用陣列,可以隨時更改陣列的長度,也可不連續儲存資料, 所以並不保證這些資料是集中的。一般情況下,這些特性很方便使用;但若這些功能都不符合您的用途,您可能會想使用型別陣列(typed arrays)。</p>
<p>有些人認為即便會發生警告,仍然<a class="external" href="http://www.andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/">不應該使用關聯陣列</a>,而應該使用 {{jsxref("Global_Objects/Object", "objects")}}。您可參考<a class="external" href="http://www.less-broken.com/blog/2010/12/lightweight-javascript-dictionaries.html">輕量級 JavaScript 字典</a>當中的範例。</p>
<h3 id="Accessing_array_elements" name="Accessing_array_elements">存取陣列元素</h3>
<p>JavaScript 陣列是 zero-indexed:陣列元素的索引值編排從 0 開始,而最後一個元素的索引值等同於陣列的 {{jsxref("Array.length", "length")}} 屬性減 1。</p>
<pre class="brush: js">var arr = ['this is the first element', 'this is the second element'];
console.log(arr[0]); // 紀錄出 'this is the first element'
console.log(arr[1]); // 記錄出 'this is the second element'
console.log(arr[arr.length - 1]); // 記錄出 'this is the second element'
</pre>
<p>Array 元素同時也是物件的屬性,與 <code>toString</code> 是一種屬性相同。但若要透過下面這種方式存取陣列元素,因為屬性名稱無效的關係,會發生語法錯誤:</p>
<pre class="brush: js">console.log(arr.0); // 語法錯誤
</pre>
<p>會造成如此的原因沒有什麼特別的,在 JavaScript 當中無法用小數點的方式來參照一個名稱開頭為數字的屬性,而必須括號的表示方式來存取。舉例來說,若您有個物件的屬性名稱為「<code>3d</code>」,就只能用括號的方式來參照。</p>
<p>請看下列範例:</p>
<pre class="brush: js">var years = [1950, 1960, 1970, 1980, 1990, 2000, 2010];
console.log(years.0); // 語法錯誤
console.log(years[0]); // 程式正常
</pre>
<pre class="brush: js">renderer.3d.setTexture(model, 'character.png'); // 語法錯誤
renderer['3d'].setTexture(model, 'character.png'); // 程式正常
</pre>
<p>注意:以這個 <code>'3d'</code> 例子來說,必須用引號將 <code>3d</code> 包起來。您也可以將 JavaScript 陣列的索引用引號包起來(例如使用 <code>years['2']</code> 而不用 <code>years[2]</code>),但這不是必要的。JavaScript 會透過隱含的 <code>toString</code>,將 <code>years[2]</code> 當中的 2 強制轉換為字串。由於這個原因,<code>'2'</code> 與 <code>'02'</code> 會參照到 <code>years</code> 物件中的不同項目,下列程式範例結果可能回傳 <code>true</code>:</p>
<pre class="brush: js">console.log(years['2'] != years['02']);
</pre>
<p>另一種類似的情況是,物件屬性剛好與保留字(!)相同的情況。這種情況下僅能透過括號表示方式當中的字串常值來存取:</p>
<pre class="brush: js">var promise = {
'var' : 'text',
'array': [1, 2, 3, 4]
};
console.log(promise['var']);
</pre>
<h3 id="Relationship_between_length_and_numerical_properties" name="Relationship_between_length_and_numerical_properties"><code>length</code> 與數值屬性的關係</h3>
<p>JavaScript 陣列的 {{jsxref("Array.length", "length")}} 屬性和其數值屬性相關。許多陣列的方法被呼叫時會參考 {{jsxref("Array.length", "length")}} 屬性的值(例如 {{jsxref("Array.join", "join")}}、{{jsxref("Array.slice", "slice")}}、{{jsxref("Array.indexOf", "indexOf")}} 等)。而有另一些方法則會去改變 {{jsxref("Array.length", "length")}} 屬性的值,如 {{jsxref("Array.push", "push")}}、{{jsxref("Array.splice", "splice")}}。</p>
<pre class="brush: js">var fruits = [];
fruits.push('banana', 'apple', 'peach');
console.log(fruits.length); // 3
</pre>
<p>如果給陣列設定一個數值屬性,其值為有效但超過當下範圍的陣列 index,JavaScript 引擎會依照此數值更新陣列的 {{jsxref("Array.length", "length")}} 屬性:</p>
<pre class="brush: js">fruits[5] = 'mango';
console.log(fruits[5]); // 'mango'
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 6
</pre>
<p>提高 {{jsxref("Array.length", "length")}} 屬性。</p>
<pre class="brush: js">fruits.length = 10;
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 10
</pre>
<div>
<p>降低 {{jsxref("Array.length", "length")}} 屬性則會刪除陣列元素。</p>
<pre class="brush: js">fruits.length = 2;
console.log(Object.keys(fruits)); // ['0', '1']
console.log(fruits.length); // 2
</pre>
<p>在 {{jsxref("Array.length")}} 頁面裡有進一步解釋。</p>
</div>
<h3 id="Creating_an_array_using_the_result_of_a_match" name="Creating_an_array_using_the_result_of_a_match">使用 match 回傳結果來建立陣列</h3>
<p>在字串與正規表示式之間的比對結果會產生一個 javascript 陣列。此陣列內含關於比對資訊的屬性與元素。 這樣的陣列由{{jsxref("RegExp.exec")}}, {{jsxref("String.match")}}, 和 {{jsxref("String.replace")}} 所產生。參考以下範例和表格,會有助於說明這些屬性和元素:</p>
<pre class="brush: js">// 比對一個字元 d,後面接著一或多個 b,再接著一個 d
// Remember matched b's and the following d
// 忽略大小寫
var myRe = /d(b+)(d)/i;
var myArray = myRe.exec('cdbBdbsbz');
</pre>
<p>這項比對結果的屬性與元素參考如下:</p>
<table class="fullwidth-table">
<tbody>
<tr>
<td class="header">屬性/元素</td>
<td class="header">說明</td>
<td class="header">範例</td>
</tr>
<tr>
<td><code>input</code></td>
<td>唯讀屬性,代表 正規表示式用以比對的原始字串。</td>
<td>cdbBdbsbz</td>
</tr>
<tr>
<td><code>index</code></td>
<td>唯讀屬性,代表在字串中比對得到的索引,是以零為基礎(從0開始)。</td>
<td>1</td>
</tr>
<tr>
<td><code>[0]</code></td>
<td>一個唯獨元素以表示最後符合的字串</td>
<td>dbBd</td>
</tr>
<tr>
<td><code>[1], ...[n]</code></td>
<td>Read-only elements that specify the parenthesized substring matches, if included in the regular expression. The number of possible parenthesized substrings is unlimited.</td>
<td>[1]: bB<br>
[2]: d</td>
</tr>
</tbody>
</table>
<h2 id="Properties" name="Properties">屬性</h2>
<dl>
<dt>Array.length</dt>
<dd><code>Array</code> 建構子的長度為 1。</dd>
<dt>{{jsxref("Array.@@species", "get Array[@@species]")}}</dt>
<dd>用來建立衍生物件的建構函數。</dd>
<dt>{{jsxref("Array.prototype")}}</dt>
<dd>可加入屬性至所有陣列物件。</dd>
</dl>
<h2 id="Methods" name="Methods">方法</h2>
<dl>
<dt>{{jsxref("Array.from()")}}</dt>
<dd>用類似陣列或可列舉物件,來建立新的 <code>Array</code> 實例。</dd>
<dt>{{jsxref("Array.isArray()")}}</dt>
<dd>若變數是陣列就回傳 true,否則回傳 false。</dd>
<dt>{{jsxref("Array.of()")}}</dt>
<dd>用可變數量的引數來建立新的 <code>Array</code> 實例,不論引數的數量或型別。</dd>
</dl>
<h2 id="Array_instances" name="Array_instances"><code>Array</code> 實例</h2>
<p>所有的陣列實例都繼承自 {{jsxref("Array.prototype")}}。若修改這個陣列建構子 (Array constructor) 的原型物件 (prototype object),將會影響所有的陣列實體。</p>
<h3 id="Methods_of_array_instances" name="Methods_of_array_instances">屬性</h3>
<div>{{page('/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype', 'Properties')}}</div>
<h3 id="Methods_of_array_instances" name="Methods_of_array_instances">方法</h3>
<h4 id="Mutator_methods" name="Mutator_methods">Mutator methods</h4>
<div>{{page('zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype', 'Mutator_methods')}}</div>
<h4 id="Accessor_methods" name="Accessor_methods">Accessor methods</h4>
<div>{{page('zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype', 'Accessor_methods')}}</div>
<h4 id="Iteration_methods" name="Iteration_methods">Iteration methods</h4>
<div>{{page('zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype', 'Iteration_methods')}}</div>
<h2 id="Array_泛型方法"><code>Array</code> 泛型方法</h2>
<div class="warning">
<p><strong>泛型陣列並非標準且已被棄用,將會在不久之後被去除。</strong> </p>
</div>
<p>有時你想將陣列方法用於字串或其他類陣列物件(像是函數 {{jsxref("Functions/arguments", "arguments", "", 1)}})。藉此操作,你將此字串視為由字元組成的陣列(反之為將其他非陣列視為物件)。如範例,若要確認字串中的每個字元是不是字母,你可能會這樣寫:</p>
<pre class="brush: js">function isLetter(character) {
return character >= 'a' && character <= 'z';
}
if (Array.prototype.every.call(str, isLetter)) {
console.log("The string '" + str + "' contains only letters!");
}
</pre>
<p>這種表示法相當浪費,JavaScript 1.6 導入了一個通用方法:</p>
<pre class="brush: js">if (Array.every(str, isLetter)) {
console.log("The string '" + str + "' contains only letters!");
}
</pre>
<p>{{jsxref("Global_Objects/String", "Generics", "#String_generic_methods", 1)}} 也同樣可用於 {{jsxref("String")}}.</p>
<p>這<strong>並非 </strong>ECMAScript 的標準,且不被非 Gecko 引擎的瀏覽器支援。你應該將你的物件用 {{jsxref("Array.from()")}} 轉為陣列,以標準替代原有的方法;雖然此方法可能不被舊的瀏覽器所支援:</p>
<pre class="brush: js">if (Array.from(str).every(isLetter)) {
console.log("The string '" + str + "' contains only letters!");
}
</pre>
<h2 id="Examples" name="Examples">範例</h2>
<h3 id="Example_Creating_an_array" name="Example:_Creating_an_array">範例:建立陣列</h3>
<p>以下範例會產生長度為 0 的 <code>msgArray</code> 陣列,然後指派字串值到 <code>msgArray[0]</code> 及 <code>msgArray[99]</code>,使陣列的長度變為 100。</p>
<pre class="brush: js">var msgArray = [];
msgArray[0] = 'Hello';
msgArray[99] = 'world';
if (msgArray.length === 100) {
console.log('The length is 100.');
}
</pre>
<h3 id="Example_Creating_a_two-dimensional_array" name="Example:_Creating_a_two-dimensional_array">建立二維陣列</h3>
<p>以下範例會用字串產生一張西洋棋盤的二維陣列。第一步是將士兵 'p' 從 (6,4) 移動至 (4,4),然後清空原本的位置 (6,4)。</p>
<pre class="brush: js">var board = [
['R','N','B','Q','K','B','N','R'],
['P','P','P','P','P','P','P','P'],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
['p','p','p','p','p','p','p','p'],
['r','n','b','q','k','b','n','r'] ];
console.log(board.join('\n') + '\n\n');
// 將士兵往前移兩步
board[4][4] = board[6][4];
board[6][4] = ' ';
console.log(board.join('\n'));
</pre>
<p>以下是輸出結果:</p>
<pre class="eval">R,N,B,Q,K,B,N,R
P,P,P,P,P,P,P,P
, , , , , , ,
, , , , , , ,
, , , , , , ,
, , , , , , ,
p,p,p,p,p,p,p,p
r,n,b,q,k,b,n,r
R,N,B,Q,K,B,N,R
P,P,P,P,P,P,P,P
, , , , , , ,
, , , , , , ,
, , , ,p, , ,
, , , , , , ,
p,p,p,p, ,p,p,p
r,n,b,q,k,b,n,r
</pre>
<h3 id="使用陣列來以表格顯示多個數值">使用陣列來以表格顯示多個數值</h3>
<pre class="brush: js">values = [];
for (var x = 0; x < 10; x++){
values.push([
2 ** x,
2 * x ** 2
])
};
console.table(values)</pre>
<p>結果會是</p>
<pre class="eval">0 1 0
1 2 2
2 4 8
3 8 18
4 16 32
5 32 50
6 64 72
7 128 98
8 256 128
9 512 162</pre>
<p>(第一欄為索引)</p>
<h2 id="Specifications" name="Specifications">規範</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">技術規格</th>
<th scope="col">狀態</th>
<th scope="col">備註</th>
</tr>
<tr>
<td>{{SpecName('ES1')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>初次定義。</td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-15.4', 'Array')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td>加入新方法:{{jsxref("Array.isArray")}}, {{jsxref("Array.prototype.indexOf", "indexOf")}}, {{jsxref("Array.prototype.lastIndexOf", "lastIndexOf")}}, {{jsxref("Array.prototype.every", "every")}}, {{jsxref("Array.prototype.some", "some")}}, {{jsxref("Array.prototype.forEach", "forEach")}}, {{jsxref("Array.prototype.map", "map")}}, {{jsxref("Array.prototype.filter", "filter")}}, {{jsxref("Array.prototype.reduce", "reduce")}}, {{jsxref("Array.prototype.reduceRight", "reduceRight")}}</td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-array-objects', 'Array')}}</td>
<td>{{Spec2('ES6')}}</td>
<td>加入新方法:{{jsxref("Array.from")}}, {{jsxref("Array.of")}}, {{jsxref("Array.prototype.find", "find")}}, {{jsxref("Array.prototype.findIndex", "findIndex")}}, {{jsxref("Array.prototype.fill", "fill")}}, {{jsxref("Array.prototype.copyWithin", "copyWithin")}}</td>
</tr>
<tr>
<td>{{SpecName('ES7', '#sec-array-objects', 'Array')}}</td>
<td>{{Spec2('ES7')}}</td>
<td>加入新方法:{{jsxref("Array.prototype.includes()")}}</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">瀏覽器相容性</h2>
<p>{{Compat("javascript.builtins.Array")}}</p>
<h2 id="See_also" name="See_also">參見</h2>
<ul>
<li><a href="/zh-TW/docs/Web/JavaScript/Guide/Working_with_Objects#Indexing_object_properties">JavaScript Guide: “Indexing object properties”</a></li>
<li><a href="/zh-TW/docs/Web/JavaScript/Guide/Predefined_Core_Objects#Array_Object">JavaScript Guide: “Predefined Core Objects: <code>Array</code> Object”</a></li>
<li><a href="/zh-TW/docs/Web/JavaScript/Reference/Operators/Array_comprehensions">Array comprehensions</a></li>
<li><a href="https://github.com/plusdude/array-generics">Polyfill for JavaScript 1.8.5 Array Generics and ECMAScript 5 Array Extras</a></li>
<li><a href="/zh-TW/docs/JavaScript_typed_arrays">Typed Arrays</a></li>
</ul>
|