EcmaScript 6
Jeśli używasz ES6, możesz zbudować tablicę przedmiotów i użyć includes
:
['a', 'b', 'c'].includes('b')
Ma to pewne nieodłączne zalety, indexOf
ponieważ może poprawnie przetestować obecność NaN
na liście i może dopasować brakujące elementy tablicy, takie jak środkowy [1, , 2]
do undefined
. includes
działa również na tablicach typu JavaScript, takich jak Uint8Array
.
Jeśli martwisz się o obsługę przeglądarki (np. IE lub Edge), możesz to sprawdzić Array.includes
na CanIUse.Com , a jeśli chcesz kierować na przeglądarkę lub brakującą wersję przeglądarki includes
, polecam polyfill.io do wypełniania.
Bez szyku
Możesz dodać nową isInList
właściwość do ciągów w następujący sposób:
if (!String.prototype.isInList) {
String.prototype.isInList = function() {
let value = this.valueOf();
for (let i = 0, l = arguments.length; i < l; i += 1) {
if (arguments[i] === value) return true;
}
return false;
}
}
Następnie użyj go w następujący sposób:
'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false
Możesz zrobić to samo dla Number.prototype
.
Array.indexOf
Jeśli korzystasz z nowoczesnej przeglądarki, indexOf
zawsze działa. Jednak w IE8 i wcześniejszych wersjach będziesz potrzebować wielokrotnego wypełnienia.
Jeśli indexOf
zwraca -1, pozycji nie ma na liście. Pamiętaj jednak, że ta metoda nie sprawdza poprawnie NaN
i chociaż może dopasować jawne undefined
, nie może dopasować brakującego elementu do undefined
jak w tablicy [1, , 2]
.
Wielokrotne wypełnianie dla indexOf
lub includes
w IE, lub dowolnej innej przeglądarce / wersji bez wsparcia
Jeśli nie chcesz korzystać z usługi takiej jak polyfill.io, jak wspomniano powyżej, zawsze możesz zawrzeć w swoim własnym kodzie źródłowym niestandardowe polypełniacze zgodne z normami. Na przykład Mozilla Developer Network ma jeden dla indexOf
.
W tej sytuacji, w której musiałem stworzyć rozwiązanie dla Internet Explorera 7, „opracowałem własną” prostszą wersję indexOf()
funkcji, która nie jest zgodna ze standardami:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(item) {
var i = this.length;
while (i--) {
if (this[i] === item) return i;
}
return -1;
}
}
Nie sądzę jednak, aby modyfikowanie Array.prototype
było najlepszą odpowiedzią na dłuższą metę. Modyfikowanie Object
i tworzenie Array
prototypów w JavaScript może prowadzić do poważnych błędów. Musisz zdecydować, czy jest to bezpieczne we własnym środowisku. Najważniejszą rzeczą jest to, że iteracja tablicy (gdy Array.prototype ma właściwości) for ... in
zwróci nową nazwę funkcji jako jeden z kluczy:
Array.prototype.blah = function() { console.log('blah'); };
let arr = [1, 2, 3];
for (let x in arr) { console.log(x); }
// Result:
0
1
2
blah // Extra member iterated over!
Twój kod może już działać, ale w momencie, gdy ktoś w przyszłości doda bibliotekę JavaScript lub wtyczkę innej firmy, która nie gorliwie chroni przed odziedziczonymi kluczami, wszystko może się zepsuć.
Starym sposobem uniknięcia tego zerwania jest, podczas wyliczania, sprawdzenie każdej wartości, aby sprawdzić, czy obiekt rzeczywiście ma ją jako właściwość nieprzechowaną, if (arr.hasOwnProperty(x))
i tylko z nią pracować x
.
Nowy ES6 sposobem na uniknięcie tego problemu dodatkowy klucz jest użycie of
zamiast in
, for (let x of arr)
. Jednakże, chyba że możesz zagwarantować, że cały twój kod i biblioteki stron trzecich ściśle trzymają się tej metody, to do celów tego pytania prawdopodobnie po prostu będziesz chciał użyć, includes
jak podano powyżej.