aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/web/javascript/reference/global_objects/array/indexof/index.html
blob: ff6bbdba763a8ffba0b3deab9606b71d5a66da53 (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
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
---
title: Array.prototype.indexOf()
slug: Web/JavaScript/Reference/Global_Objects/Array/indexOf
tags:
  - Array
  - JavaScript
  - Method
  - Prototype
  - Reference
  - polyfill
translation_of: Web/JavaScript/Reference/Global_Objects/Array/indexOf
---
<div>{{JSRef}}</div>

<p><code><strong>indexOf()</strong></code> 方法會回傳給定元素於陣列中第一個被找到之索引,若不存在於陣列中則回傳 -1。</p>

<div class="note">
<p><strong>備註:</strong>若是調用字串的方法,請參閱 {{jsxref("String.prototype.indexOf()")}}</p>
</div>

<div>{{EmbedInteractiveExample("pages/js/array-indexof.html")}}</div>



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

<pre class="syntaxbox"><var>arr</var>.indexOf(<var>searchElement[</var>, <var>fromIndex]</var>)</pre>

<h3 id="參數">參數</h3>

<dl>
 <dt><code>searchElement</code></dt>
 <dd>欲在陣列中搜尋的元素。</dd>
 <dt><code>fromIndex</code> {{optional_inline}}</dt>
 <dd>陣列中搜尋的起始索引。若這個索引值大於或等於陣列長度,會直接回傳 -1,意即不會在陣列中搜尋。如果索引值是一個負數,會從陣列的最後一個往回算,最後一個的索引值為 -1,以此類推。注意:儘管往回算,但依然會從左往右全部搜尋。如果負數索引值在回頭計算之後仍然小於 0,則會從左往右全部搜尋。 這個參數的預設值為 0(即搜尋整個陣列)。</dd>
</dl>

<h3 id="回傳值">回傳值</h3>

<p>在陣列中找到的第一個元素索引值;沒找到則為 <strong>-1</strong></p>

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

<p><code>indexOf()</code><a href="/zh-TW/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Using_the_Equality_Operators">嚴格相等(strict equality,<code>===</code></a>的方式比較陣列中的元素與 <code>searchElement</code> 是否相等。</p>

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

<h3 id="使用_indexOf()">使用 <code>indexOf()</code></h3>

<p>下面範例使用<code>indexOf()</code>來定位在陣列中的值。</p>

<pre class="brush: js">var array = [2, 9, 9];
array.indexOf(2);     // 0
array.indexOf(7);     // -1
array.indexOf(9, 2);  // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0
</pre>

<h3 id="尋找該元素所有出現在陣列中的位置">尋找該元素所有出現在陣列中的位置</h3>

<pre class="brush: js">var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
  indices.push(idx);
  idx = array.indexOf(element, idx + 1);
}
console.log(indices);
// [0, 2, 4]
</pre>

<h3 id="尋找元素是否存在於陣列中,若沒有則加入到陣列裡。">尋找元素是否存在於陣列中,若沒有則加入到陣列裡。</h3>

<pre class="brush: js">function updateVegetablesCollection (veggies, veggie) {
    if (veggies.indexOf(veggie) === -1) {
        veggies.push(veggie);
        console.log('New veggies collection is : ' + veggies);
    } else if (veggies.indexOf(veggie) &gt; -1) {
        console.log(veggie + ' already exists in the veggies collection.');
    }
}

var veggies = ['potato', 'tomato', 'chillies', 'green-pepper'];

updateVegetablesCollection(veggies, 'spinach');
// New veggies collection is : potato,tomato,chillies,green-pepper,spinach
updateVegetablesCollection(veggies, 'spinach');
// spinach already exists in the veggies collection.
</pre>

<h2 id="Polyfill">Polyfill</h2>

<p><code>indexOf()</code> was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all browsers. You can work around this by utilizing the following code at the beginning of your scripts. This will allow you to use <code>indexOf()</code> when there is still no native support. This algorithm matches the one specified in ECMA-262, 5th edition, assuming {{jsxref("Global_Objects/TypeError", "TypeError")}} and {{jsxref("Math.abs()")}} have their original values.</p>

<p> </p>

<pre class="brush: js">if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function indexOf(member, startFrom) {
    /*
    In non-strict mode, if the `this` variable is null or undefined, then it is
    set to the window object. Otherwise, `this` is automatically converted to an
    object. In strict mode, if the `this` variable is null or undefined, a
    `TypeError` is thrown.
    */
    if (this == null) {
      throw new TypeError("Array.prototype.indexOf() - can't convert `" + this + "` to object");
    }

    var
      index = isFinite(startFrom) ? Math.floor(startFrom) : 0,
      that = this instanceof Object ? this : new Object(this),
      length = isFinite(that.length) ? Math.floor(that.length) : 0;

    if (index &gt;= length) {
      return -1;
    }

    if (index &lt; 0) {
      index = Math.max(length + index, 0);
    }

    if (member === undefined) {
      /*
        Since `member` is undefined, keys that don't exist will have the same
        value as `member`, and thus do need to be checked.
      */
      do {
        if (index in that &amp;&amp; that[index] === undefined) {
          return index;
        }
      } while (++index &lt; length);
    } else {
      do {
        if (that[index] === member) {
          return index;
        }
      } while (++index &lt; length);
    }

    return -1;
  };
}</pre>

<p> </p>

<p>However, if you are more interested in all the little technical bits defined by the ECMA standard, and are less concerned about performance or conciseness, then you may find this more descriptive polyfill to be more usefull.</p>

<pre class="brush: js">// Production steps of ECMA-262, Edition 5, 15.4.4.14
// Reference: http://es5.github.io/#x15.4.4.14
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {

    var k;

    // 1. Let o be the result of calling ToObject passing
    //    the this value as the argument.
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }

    var o = Object(this);

    // 2. Let lenValue be the result of calling the Get
    //    internal method of o with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = o.length &gt;&gt;&gt; 0;

    // 4. If len is 0, return -1.
    if (len === 0) {
      return -1;
    }

    // 5. If argument fromIndex was passed let n be
    //    ToInteger(fromIndex); else let n be 0.
    var n = fromIndex | 0;

    // 6. If n &gt;= len, return -1.
    if (n &gt;= len) {
      return -1;
    }

    // 7. If n &gt;= 0, then Let k be n.
    // 8. Else, n&lt;0, Let k be len - abs(n).
    //    If k is less than 0, then let k be 0.
    k = Math.max(n &gt;= 0 ? n : len - Math.abs(n), 0);

    // 9. Repeat, while k &lt; len
    while (k &lt; len) {
      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the
      //    HasProperty internal method of o with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      //    i.  Let elementK be the result of calling the Get
      //        internal method of o with the argument ToString(k).
      //   ii.  Let same be the result of applying the
      //        Strict Equality Comparison Algorithm to
      //        searchElement and elementK.
      //  iii.  If same is true, return k.
      if (k in o &amp;&amp; o[k] === searchElement) {
        return k;
      }
      k++;
    }
    return -1;
  };
}
</pre>

<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('ES5.1', '#sec-15.4.4.14', 'Array.prototype.indexOf')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>Initial definition. Implemented in JavaScript 1.6.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-array.prototype.indexof', 'Array.prototype.indexOf')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-array.prototype.indexof', 'Array.prototype.indexOf')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
 </tbody>
</table>

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

<div>


<p>{{Compat("javascript.builtins.Array.indexOf")}}</p>
</div>

<h2 id="相容性備註">相容性備註</h2>

<ul>
 <li>Starting with Firefox 47 {{geckoRelease(47)}},  this method will no longer return <code>-0</code>. For example, <code>[0].indexOf(0, -0)</code> will now always return <code>+0</code> ({{bug(1242043)}}).</li>
</ul>

<h2 id="參見">參見</h2>

<ul>
 <li>{{jsxref("Array.prototype.lastIndexOf()")}}</li>
 <li>{{jsxref("TypedArray.prototype.indexOf()")}}</li>
 <li>{{jsxref("String.prototype.indexOf()")}}</li>
</ul>