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
|
---
title: Array.prototype.findIndex()
slug: Web/JavaScript/Reference/Global_Objects/Array/findIndex
tags:
- Array
- ECMAScript 2015
- JavaScript
- Method
- Prototype
- Reference
- polyfill
translation_of: Web/JavaScript/Reference/Global_Objects/Array/findIndex
---
<div>{{JSRef}}</div>
<p><code><strong>findIndex()</strong></code> 方法將依據提供的測試函式,尋找陣列中符合的元素,並返回其 <strong>index</strong>(索引)。如果沒有符合的對象,將返回 -1 。</p>
<div>{{EmbedInteractiveExample("pages/js/array-findindex.html")}}</div>
<div> </div>
<p>另請參見 {{jsxref("Array.find", "find()")}} 方法,它返回陣列中找到的元素的<strong>值</strong>,而不是其索引。</p>
<h2 id="語法">語法</h2>
<pre class="syntaxbox"><var>arr</var>.findIndex(<var>callback</var>[, <var>thisArg</var>])</pre>
<h3 id="參數">參數</h3>
<dl>
<dt><code>callback</code></dt>
<dd>針對陣列中的每個元素,都會執行該回呼函式,執行時會自動傳入下面三個參數:
<dl>
<dt><code>element</code></dt>
<dd>當前元素。</dd>
<dt><code>index</code>{{optional_inline}}</dt>
<dd>當前元素的索引。</dd>
<dt><code>array</code>{{optional_inline}}</dt>
<dd>呼叫 <code>findIndex</code> 的陣列。</dd>
</dl>
</dd>
<dt><code>thisArg</code>{{optional_inline}}</dt>
<dd>可選的。執行 <strong>callback</strong> 時作為 this 對象的值。</dd>
</dl>
<h3 id="回傳值">回傳值</h3>
<p>An index in the array if an element passes the test; otherwise, <strong>-1</strong>.</p>
<h2 id="描述">描述</h2>
<p><code>findIndex</code> 方法對陣列中的每一個索引:<code>0..length-1</code>(含)的元素執行一次 <code>callback</code> 直到有一個 <code>callback</code> 返回 truthy 值(一個可強制轉型(coerces)為 <code>true</code> 的值)。如果找到了一個這樣的元素,則 <code>findIndex</code> 將會立刻返回此次迭代的索引。若回呼函式從未回傳一個 truthy 值,或陣列的 <code>length</code> 為 0,則 <code>findIndex</code> 將會返回 -1。不像其他的陣列方法如 <code>some</code> 那樣,於稀疏(sparse)陣列上 <code>callback</code> <strong>仍會</strong>被呼叫,即使該索引的項目在陣列中並不存在。</p>
<p><code>callback</code> 被呼叫時會傳入三個參數:元素的值、元素的索引,以及被迭代的陣列物件。</p>
<p>如果一個 <code>thisArg</code> 參數被提供給 <code>findIndex</code>,它將會被當作 <code>this</code> 使用在每次回呼函式被調用的時候。如果沒有被提供,將會使用 {{jsxref("undefined")}}。</p>
<p><code>findIndex</code> 不會修改呼叫此方法的陣列。</p>
<p>在第一次呼叫 <code>callback</code> 函式時會確定元素的索引範圍,因此在 <code>findIndex</code> 方法開始執行之後添加到陣列的新元素將不會被 <code>callback</code> 函式訪問到。如果陣列中一個尚未被 <code>callback</code> 函式訪問到的元素的值被 <code>callback</code> 函式所改變,那麼當 <code>callback</code> 函式訪問到它時,它的值是將是根據它在陣列中的索引所訪問到的當前值;被刪除的元素仍然會被訪問到。</p>
<h2 id="範例">範例</h2>
<h3 id="尋找陣列中首個質數元素的索引">尋找陣列中首個質數元素的索引</h3>
<p>以下的範例演示了如何查找一個陣列中首個質數元素的索引,找不到則返回 -1。</p>
<pre class="brush: js">function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 12].findIndex(isPrime)); // 2
</pre>
<h3 id="使用箭頭函式尋找索引">使用箭頭函式尋找索引</h3>
<p>以下範例為使用箭頭函式尋找水果的索引。</p>
<pre class="brush: js">const fruits = ["apple", "banana", "cantaloupe", "blueberries", "grapefruit"];
const index = fruits.findIndex(fruit => fruit === "blueberries");
console.log(index); // 3
console.log(fruits[index]); // blueberries
</pre>
<h2 id="Polyfill">Polyfill</h2>
<pre class="brush: js">// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, 'findIndex', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return k.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return k;
}
// e. Increase k by 1.
k++;
}
// 7. Return -1.
return -1;
}
});
}
</pre>
<p>如果您需要相容過時的不支援 <code><a href="/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">Object.defineProperty</a></code> 的 JavaScript 引擎,最好不要使用 polyfill 來填充 <code>Array.prototype</code> 方法,因為無法使它們成為不可枚舉的(non-enumerable)屬性。</p>
<h2 id="規範">規範</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('ES2015', '#sec-array.prototype.findindex', 'Array.prototype.findIndex')}}</td>
<td>{{Spec2('ES2015')}}</td>
<td>Initial definition.</td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-array.prototype.findIndex', 'Array.prototype.findIndex')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
<div>
<p>{{Compat("javascript.builtins.Array.findIndex")}}</p>
</div>
<h2 id="參見">參見</h2>
<ul>
<li>{{jsxref("Array.prototype.find()")}}</li>
<li>{{jsxref("Array.prototype.indexOf()")}}</li>
</ul>
|