EcmaScript 6
Если вы используете ES6, вы можете создать массив элементов и использовать includes
:
['a', 'b', 'c'].includes('b')
Это имеет некоторые неотъемлемые преимущества по сравнению с indexOf
, поскольку оно может правильно проверять наличие NaN
в списке и может сопоставлять отсутствующие элементы массива, такие как средний, в [1, , 2]
с undefined
. includes
также работает на массивах с типом JavaScript , таких как Uint8Array
.
без массива
Вы можете добавить новое свойство 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
в Internet Explorer 8 и более ранних версиях или в любом другом браузере без него
Вы всегда можете использовать совместимый со стандартами пользовательский полифилл , чтобы сделать это в старых браузерах.
В этой ситуации, когда мне нужно было найти решение для 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
, как указано выше.