indexOf()
メソッドは引数に与えられた内容と同じ内容を持つ配列要素の内、最初のものの添字を返します。存在しない場合は -1
を返します。
注: String のメソッドについては、String.prototype.indexOf()
を見てください。
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
構文
array.indexOf(searchElement[, fromIndex]);
引数
searchElement
- 検索する配列要素です。
fromIndex
Optional- 検索を始める添字です。初期値は
0
、つまり配列全体が検索されます。もしこの添字が配列の長さ以上だと、-1
が返され、配列は検索されません。負の数の場合、これは配列の終わりからのオフセットとみなされます。この添字が負の数であっても、配列は前から後ろに検索されることに注意してください。負の添え字の絶対値が配列の長さを超えた場合、配列全体が検索されます。
返値
見つかった配列要素の最初のインデックスです。見つからなかった場合、 -1 です。
説明
indexOf()
は searchElement
と配列の要素を 厳密な同値(三重イコール演算子 ===
で使われるのと同じ方法)を使って比較します。
例
indexOf()
を使う
以下の例は indexOf()
を使って、配列中のある値の位置を探しています。
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
ある要素の存在をすべて見つける
以下の例は indexOf()
を使って、与えられた配列中のある値の添字すべてを探しています。push
を使って、値が見つかる度に別の配列にその添字を追加しています。
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]
要素が配列内に存在するかどうかを調べ、配列を更新する
function updateVegetablesCollection (veggies, veggie) { if (veggies.indexOf(veggie) === -1) { veggies.push(veggie); console.log('New veggies collection is : ' + veggies); } else if (veggies.indexOf(veggie) > -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.
Polyfill
indexOf()
メソッドは ECMA-262 第 5 版で追加されたものであり、すべてのブラウザーで動作するわけではありません。次のコードをスクリプトの先頭に追加することにより、indexOf()
がネイティブでサポートされていない環境でも、これが使用可能となります。これは ECMA-262 第 5 版で定められたアルゴリズムと完全に同じものです。TypeError
と Math.abs()
がオリジナルの値を持つ事を仮定しています。
if (!Array.prototype.indexOf) Array.prototype.indexOf = (function(Object, max, min){ "use strict"; return function indexOf(member, fromIndex) { if(this===null||this===undefined)throw TypeError("Array.prototype.indexOf called on null or undefined"); var that = Object(this), Len = that.length >>> 0, i = min(fromIndex | 0, Len); if (i < 0) i = max(0, Len+i); else if (i >= Len) return -1; if(member===void 0){ for(; i !== Len; ++i) if(that[i]===void 0 && i in that) return i; // undefined }else if(member !== member){ for(; i !== Len; ++i) if(that[i] !== that[i]) return i; // NaN }else for(; i !== Len; ++i) if(that[i] === member) return i; // all else return -1; // if the value was not found, then return -1 }; })(Object, Math.max, Math.min);
ですが、ECMA 標準で定義された技術的な部分に興味があり、パフォーマンスや簡潔さを意識しない場合、以下のような、より説明的な polyfill が役立つことがあるでしょう。
// 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. o を ToObject(this) とします。 if (this == null) { throw new TypeError('"this" is null or not defined'); } var o = Object(this); // 2. lenValue を、"length" を引数として o の [[Get]] 内部メソッドを呼んだ結果とします。 // 3. len を ToUint32(lenValue) とします。 var len = o.length >>> 0; // 4. len が 0 の場合、-1 を返します。 if (len === 0) { return -1; } // 5. n を fromIndex 引数が存在する場合は ToInteger(fromIndex) と、 // 存在しない場合は 0 とします。 var n = fromIndex | 0; // 6. n が len 以上の場合 -1 を返します。 if (n >= len) { return -1; } // 7. n が 0 以上の場合 k を n とします。 // 8. n が 0 未満の場合 k を len - abs(n) とします。 // k が 0 未満の場合 k を 0 とします。 k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); // 9. k が len 未満の間は以下を繰り返します。 while (k < len) { // a. Pk を ToString(k) とします。 // これは暗黙的に in 演算子の左辺値です。 // b. kPresent を Pk を引数として o の // [[HasProperty]] 内部メソッドを呼んだ結果とします。 // このステップは c と組み合わせることができます。 // c. kPresent が真の場合 // i. elementK を ToString(k) を引数として // o の [[Get]] 内部メソッドを呼んだ結果とします。 // ii. same を searchElement と elementK で // 厳密な同一比較アルゴリズムを行った結果とします。 // iii. same が真の場合 k を返します。 if (k in o && o[k] === searchElement) { return k; } k++; } return -1; }; }
仕様
仕様書 | 策定状況 | コメント |
---|---|---|
ECMAScript 5.1 (ECMA-262) Array.prototype.indexOf の定義 |
標準 | 初回定義です。JavaScript 1.6 で実装されました。 |
ECMAScript 2015 (6th Edition, ECMA-262) Array.prototype.indexOf の定義 |
標準 | |
ECMAScript Latest Draft (ECMA-262) Array.prototype.indexOf の定義 |
ドラフト |
ブラウザー実装状況
デスクトップ | モバイル | サーバー | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
基本対応 | Chrome 完全対応 あり | Edge 完全対応 あり | Firefox 完全対応 1.5 | IE 完全対応 9 | Opera 完全対応 あり | Safari 完全対応 あり | WebView Android 完全対応 あり | Chrome Android 完全対応 あり | Edge Mobile 完全対応 あり | Firefox Android 完全対応 4 | Opera Android 完全対応 あり | Safari iOS 完全対応 あり | Samsung Internet Android 完全対応 あり | nodejs 完全対応 あり |
凡例
- 完全対応
- 完全対応
互換性ノート
- Firefox 47 (Firefox 47 / Thunderbird 47 / SeaMonkey 2.44) 以上では、このメソッドはもはや
-0
を返しません。例に[0].indexOf(0, -0)
として、今は常に+0
を返します(バグ 1242043)。