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) > -1 false'tır
  • [NaN].includes(NaN) true değ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 NaN için başarısız olur, çünkü indexOf Sı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.includes yöntemi eklenmesini öneriyoruz

if (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.indexOf ve String.prototype.includes benzeri bir şekilde fromIndex parametresi ekliyoruz.

Daha fazla bilgi:

  • SameValueZero algoritması
  • Katı Eşitlik Karşılaştırma algoritması

Cevap #2

Teknik olarak

  • NaN veya undefined, indexOf kullanı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
  • includes ayrı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 bir boolean döndürdüğü açıktır.
  • Bir şeyin bir stringde veya dizide var olup olmadığını bilmek için arr.indexOf('searchedElement') !== -1 kullanmak 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,08
  • includes=> %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ı)

  1. indexOf, Katı Eşitlik Karşılaştırmasını kullanırken, includes SameValueZero algoritmasını kullanır. Bu nedenle, aşağıdaki iki fark noktası ortaya çıkar.

  2. Felix Kling'in belirttiği gibi, NaN durumunda davranış farklıdır.

let arr = [NaN];

arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
  1. Davranış undefined durumunda 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.

İlgili makaleler