javascript - Array.prototype.includes vs. Array.prototype.indexOf
Geliştirilmiş okunabilirliğin ötesinde, includes'in indexOf üzerine herhangi bir avantajı var mı? Bana ikisi de aynı gibi görünüyor.
Bunun arasındaki fark nedir
var x = [1,2,3].indexOf(1) > -1; //true
Ve bu?
var y = [1,2,3].includes(1); //true
Cevap #1
özet: NaN farklı şekilde ele alınır:
[NaN].indexOf(NaN) > -1false'tır[NaN].includes(NaN)truedeğerindedir
Öneriden:
Motivasyon
ECMAScript dizilerini kullanırken, dizinin bir elemanı içerip içermediğini belirlemek genellikle istenir. Bunun için yaygın olan yöntem şudur
if (arr.indexOf(el) !== -1) { ... }çeşitli diğer olasılıklarla, örn.
arr.indexOf(el) >= 0, veya hatta~arr.indexOf(el).Bu desenler iki sorun gösteriyor:
- Onlar 'ne demek istediğini söylemeyi' başaramazlar: Dizide bir öğe olup olmadığını sormak yerine, o öğenin dizideki ilk geçtiği indeksin ne olduğunu sorarsınız ve sonra cevabı belirlemek için onu karşılaştırır veya bit-manipülasyon yaparsınız.
- Onlar
NaNiçin başarısız olur, çünküindexOfSıkı Eşitlik Karşılaştırması kullanır ve bu yüzden[NaN].indexOf(NaN) === -1.Önerilen Çözüm
Yukarıdaki desenlerin şu şekilde yeniden yazılabilmesi için bir
Array.prototype.includesyöntemi eklenmesini öneriyoruzif (arr.includes(el)) { ... }Bu, yukarıdakine neredeyse aynı anlamsal yapıya sahiptir, ancak Katı Eşitlik Karşılaştırması yerine SameValueZero karşılaştırma algoritmasını kullanır, böylece
[NaN].includes(NaN)ifadesi doğru olur.Böylece, bu öneri mevcut koddaki her iki problemi de çözer.
Ayrıca tutarlılık için
Array.prototype.indexOfveString.prototype.includesbenzeri bir şekildefromIndexparametresi ekliyoruz.
Daha fazla bilgi:
SameValueZeroalgoritmasıKatı Eşitlik Karşılaştırmaalgoritması
Cevap #2
Teknik olarak
NaNveyaundefined,indexOfkullanıldığında bulunabilir olmayacaktır.
[NaN].indexOf(NaN) // => -1 (not found)
[NaN].includes(NaN) // => true
[undefined].indexOf(undefined) // => -1 (not found)
[undefined].includes(undefined) // => true
includesayrıca elemanın hangi indekste bulunduğunu öğrenmek istiyorsanız işe yaramaz.Bir dize aranırken,
includes, indexOf'un aksine regexpeleri kabul eder
Okunabilirlik
arr.includes('searchedElement')söylediğini yapar ve birbooleandöndürdüğü açıktır.- Bir şeyin bir stringde veya dizide var olup olmadığını bilmek için
arr.indexOf('searchedElement') !== -1kullanmak daha az okunabilir.
Performanslar
Konuyla ilgili bu makaleye göre kayda değer bir fark yoktur, ancak includes biraz daha yavaş olabilir.
Tarih
indexOf, includes'den çok önce oluşturuldu.
Tarayıcı desteği
indexOf=> %97,08includes=> %97,51
Yani her ikisi de güvenle kullanılabilir.
Cevap #3
.indexOf() ve .includes() yöntemleri, bir dizide bir öğe aramak veya verilen bir string içinde bir karakter/alt string aramak için kullanılabilir.
Dizide Kullanım
(ECMAScript Spesifikasyonuna Bağlantı)
indexOf, Katı Eşitlik Karşılaştırmasını kullanırken,includesSameValueZero algoritmasını kullanır. Bu nedenle, aşağıdaki iki fark noktası ortaya çıkar.Felix Kling'in belirttiği gibi,
NaNdurumunda davranış farklıdır.
let arr = [NaN];
arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
- Davranış
undefineddurumunda da farklıdır.
let arr = [ , , ];
arr.indexOf(undefined); // returns -1; meaning undefined is not present
arr.includes(undefined); // returns true
Dizide Kullanım
(ECMAScript Spesifikasyonu'na Bağlantı)
1. Eğer indexOf'a bir RegExp geçirirseniz, RegExp'i bir dize olarak ele alacak ve eğer bulunursa dizenin indeksini döndürecektir. Ancak, includes'a bir RegExp geçirirseniz, bir istisna fırlatacaktır.
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
Performans
GLAND_PROPRE'in belirttiği gibi, includes, indexOf'dan biraz (çok çok küçük) daha yavaş olabilir (çünkü ilk argüman olarak bir regex olup olmadığını kontrol etmesi gerekiyor) ama gerçek anlamda bu fazla bir fark yaratmaz ve önemsizdir.
Tarih
String.prototype.includes(), ECMAScript 2015'te tanıtılırken Array.prototype.includes() ECMAScript 2016'da tanıtıldı. Tarayıcı desteği ile ilgili olarak, bunları akıllıca kullanın.
String.prototype.indexOf() ve Array.prototype.indexOf() ECMAScript'in ES5 sürümünde mevcuttur ve bu nedenle tüm tarayıcılar tarafından desteklenir.
