Array.prototype.includes vs. Array.prototype.indexOf

112

Selain keterbacaan yang lebih baik, apakah ada keuntungan includeslebih dari itu indexOf? Mereka tampak identik dengan saya.

Apa perbedaan antara ini

var x = [1,2,3].indexOf(1) > -1; //true

Dan ini?

var y = [1,2,3].includes(1); //true
Matt
sumber
12
includesmemiliki dukungan browser yang jauh lebih buruk.
Quentin
4
Perhatikan bahwa includesitu bukan bagian dari ES6 / ES2015. Ini adalah proposal untuk versi ECMAScript berikutnya dan akan ditambahkan tahun ini.
Felix Kling
4
hanya ingin menyebutkan bahwa includesTIDAK didukung di IE sama sekali
ZvKa

Jawaban:

138

tl; dr: NaN diperlakukan berbeda:

  • [NaN].indexOf(NaN) > -1 adalah false
  • [NaN].includes(NaN) adalah true

Dari proposal :

Motivasi

Saat menggunakan array ECMAScript, biasanya diinginkan untuk menentukan apakah array menyertakan elemen. Pola yang berlaku untuk ini adalah

if (arr.indexOf(el) !== -1) {
    ...
}

dengan berbagai kemungkinan lain, misalnya arr.indexOf(el) >= 0, atau bahkan ~arr.indexOf(el).

Pola-pola ini menunjukkan dua masalah:

  • Mereka gagal untuk "mengatakan apa yang Anda maksud": alih-alih bertanya tentang apakah array menyertakan elemen, Anda bertanya apa indeks kemunculan pertama elemen itu dalam array, dan kemudian membandingkannya atau memutarnya, untuk menentukan jawaban atas pertanyaan Anda yang sebenarnya.
  • Mereka gagal NaN, karena indexOfmenggunakan Perbandingan Kesetaraan Ketat dan karenanya [NaN].indexOf(NaN) === -1.

Solusi yang Diusulkan

Kami mengusulkan penambahan Array.prototype.includesmetode, sehingga pola di atas dapat ditulis ulang sebagai

if (arr.includes(el)) {
    ...
}

Ini memiliki semantik yang hampir sama seperti di atas, kecuali bahwa ia menggunakan algoritma perbandingan SameValueZero alih-alih Perbandingan Persamaan Ketat, sehingga menjadikannya [NaN].includes(NaN)benar.

Dengan demikian, proposal ini memecahkan kedua masalah yang terlihat pada kode yang ada.

Kami juga menambahkan fromIndexparameter, mirip dengan Array.prototype.indexOfdan String.prototype.includes, untuk konsistensi.


Informasi lebih lanjut:

Felix Kling
sumber
1
Hanya setengah dari kebenaran. Juga berbeda: elemen yang hilang diperlakukan sebagai undefinedoleh .includes()dan tidak dianggap oleh .indexOf().
Robert Siemer
11

Jika Anda bertanya-tanya tentang kinerja, untuk saat ini, indexOf lebih cepat, tetapi tes JSperf ini cenderung menunjukkan bahwa lebih banyak waktu berlalu, lebih banyak includes()akan lebih cepat daripada indexOf(saya kira itu akan dioptimalkan lebih lanjut).

IMHO, saya juga lebih suka menulis if (arr.includes(el)) {}karena lebih jelas dan lebih mudah dirawat daripadaif (arr.indexOf(el) !== -1) {}

538ROMEO
sumber
1
Sepertinya perbedaan performa tidak begitu jelas. Firefox seluler saya menunjukkan bahwa indexOf sebenarnya lebih cepat. Beberapa versi Chrome bertindak sama ... Namun perbedaannya tampaknya dapat diabaikan dalam penerapan saat ini.
Nux
8

.indexOf()dan .includes()metode dapat digunakan untuk mencari elemen dalam array atau untuk mencari karakter / substring dalam string tertentu.

Penggunaan di Array

( Tautan ke Spesifikasi ECMAScript)

  1. indexOfmenggunakan Perbandingan Persamaan Ketat sedangkan includesmenggunakan algoritma SameValueZero . Karena alasan inilah, dua poin perbedaan berikut muncul.

  2. Seperti yang dikemukakan Felix Kling , perilakunya berbeda dalam kasus NaN.

let arr = [NaN];

arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
  1. Perilaku ini juga berbeda dalam kasus undefined.
let arr = [ , , ];

arr.indexOf(undefined); // returns -1; meaning undefined is not present
arr.includes(undefined); // returns true

Penggunaan dalam String

( Tautan ke Spesifikasi ECMAScript)

  1. Jika Anda meneruskan RegExp ke indexOf, itu akan memperlakukan RegExp sebagai string dan akan mengembalikan indeks string, jika ditemukan. Namun, jika Anda meneruskan RegExp ke includes, itu akan memunculkan pengecualian.
let str = "javascript";

str.indexOf(/\w/); // returns -1 even though the elements match the regex because /\w/ is treated as string
str.includes(/\w/); // throws TypeError: First argument to String.prototype.includes must not be a regular expression

Performa

Seperti yang 538ROMEO tunjukkan,includes mungkin sedikit (sangat kecil) sedikit lebih lambat (karena perlu memeriksa regex sebagai argumen pertama) daripada indexOftetapi pada kenyataannya, ini tidak membuat banyak perbedaan dan dapat diabaikan.

Sejarah

String.prototype.includes() diperkenalkan di ECMAScript 2015 sedangkan Array.prototype.includes() diperkenalkan di ECMAScript 2016. Sehubungan dengan dukungan browser, gunakan dengan bijak.

String.prototype.indexOf()dan Array.prototype.indexOf()hadir dalam ECMAScript edisi ES5 dan karenanya didukung oleh semua browser.

Srishti
sumber
indexOfmemberikan truesetelah secara eksplisit mengatur undefinedke dalam array: let arr=[undefined];atau let arr=[];arr[0]=undefined;Sekarangarr.indexOf(undefined) === 0
Jay Dadhania
Anda adalah satu-satunya yang menunjukkan perbedaan dengan undefined: Alasannya adalah yang .includesmemperlakukan elemen yang hilang sebagai undefined, sambil .indexOf()mengabaikannya. Anda juga dapat "membuat" elemen yang hilang dengan arr[number beyond length] = whatever.
Robert Siemer
Tidak ada yang meminta string, tetapi komentar Anda menunjukkan bahwa .includes()hanya makan string. Pada kenyataannya kedua metode memaksa apa pun menjadi string sebaik mungkin. Regex secara khusus dikecualikan sebagai argumen untuk .includes()ke memungkinkan untuk penambahan masa depan dengan standar sesuai dengan rancangan saat ini.
Robert Siemer
4

Secara konseptual Anda harus menggunakan indexOf ketika Anda ingin menggunakan posisi indexOf hanya memberikan Anda untuk mengekstrak nilai atau beroperasi di atas array, yaitu menggunakan slice, shift atau split setelah Anda mendapatkan posisi elemen. Di sisi lain, Use Array.includes hanya untuk mengetahui apakah nilainya ada di dalam array dan bukan posisinya karena Anda tidak mempedulikannya.

Sebastian Gomez
sumber
0

indexOf()dan includes()keduanya dapat digunakan untuk menemukan elemen dalam larik, namun setiap fungsi menghasilkan nilai pengembalian yang berbeda.

indexOfmengembalikan angka ( -1jika elemen tidak ada dalam array, atau posisi array jika elemen ada).

includes()mengembalikan nilai boolean ( trueatau false).

Kruti
sumber
Hai Kruti, pertanyaan ini sudah dijawab dan jawabannya diterima. Selanjutnya, Anda dapat melihat bagaimana jawaban Anda hanya berisi info yang sudah dikatakan di jawaban lain. Pertanyaannya, pada akhirnya sudah berumur 4 tahun. Harap berikan panduan tentang pertanyaan terbaru atau pertanyaan yang belum terjawab. Terima kasih
leonardfactory