EcmaScript 6
Если вы используете ES6, вы можете создать массив элементов и использовать includes
:
['a', 'b', 'c'].includes('b')
Это имеет некоторые неотъемлемые преимущества по сравнению с indexOf
тем, что он может правильно проверять наличие NaN
в списке и может сопоставлять отсутствующие элементы массива, такие как средний, [1, , 2]
с undefined
. includes
также работает с типизированными массивами JavaScript, такими как Uint8Array
.
Если вас беспокоит поддержка браузера (например, для IE или Edge), вы можете проверить Array.includes
на CanIUse.Com , и если вы хотите указать браузер или версию браузера, которая отсутствует includes
, я рекомендую polyfill.io для полизаполнения.
Без массива
Вы можете добавить новое isInList
свойство в строки следующим образом:
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;
}
}
Тогда используйте это так:
'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false
Вы можете сделать то же самое для Number.prototype
.
Array.indexOf
Если вы используете современный браузер, indexOf
всегда работает. Однако для IE8 и более ранних версий вам понадобится полифилл.
Если indexOf
возвращается -1, элемент отсутствует в списке. Однако помните, что этот метод не будет правильно проверять NaN
, и хотя он может соответствовать явному undefined
, он не может сопоставить отсутствующий элемент с тем, undefined
что и в массиве [1, , 2]
.
Polyfill для indexOf
или includes
в IE, или любой другой браузер / версия без поддержки
Если вы не хотите использовать такой сервис, как polyfill.io, как упомянуто выше, вы всегда можете включить в свой собственный пользовательский полифилл, совместимый со стандартами исходного кода. Например, в Mozilla Developer Network есть один для indexOf
.
В этой ситуации, когда мне нужно было найти решение для Internet Explorer 7, я «свернул свою» более простую версию indexOf()
функции, которая не соответствует стандартам:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(item) {
var i = this.length;
while (i--) {
if (this[i] === item) return i;
}
return -1;
}
}
Однако я не думаю, что изменение Array.prototype
- лучший ответ в долгосрочной перспективе. Модификации Object
и Array
прототипы в JavaScript могут привести к серьезным ошибкам. Вам нужно решить, насколько это безопасно в вашей среде. В первую очередь следует отметить, что повторение массива (когда Array.prototype имеет добавленные свойства) с for ... in
вернет новое имя функции в качестве одного из ключей:
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!
Ваш код может работать сейчас, но в тот момент, когда кто-то в будущем добавит стороннюю библиотеку JavaScript или плагин, который не будет рьяно защищать от унаследованных ключей, все может сломаться.
Старый способ избежать этой поломки - во время перечисления проверять каждое значение, чтобы увидеть, действительно ли объект имеет его как не наследуемое свойство if (arr.hasOwnProperty(x))
и только затем работать с ним x
.
Новый ES6 способ избежать этого дополнительного ключа проблемы заключается в использовании of
вместо in
, for (let x of arr)
. Однако, если вы не можете гарантировать, что весь ваш код и сторонние библиотеки строго придерживаются этого метода, то для целей этого вопроса вы, вероятно, просто захотите использовать, includes
как указано выше.