JavaScript: includes vs indexOf

Починаючи з ECMAScript 2016 в JavaScript з'явився новий метод includes для роботи з масивами. По своїй суті він дуже сильно нагадує indexOf. У цій статті я хочу розглянути детальніше для чого був введений цей метод і в чому його відмінність від indexOf.

image


Масиви
Отже, метод Array.prototype.includes визначає міститься в масиві шукане значення і повертає true або false. Таким чином, на відміну від indexOf, який повертає ціле число, includes повертає значення типу boolean. Це нововведення допоможе розробникам писати більш чистий і зрозумілий код.

Наприклад, ось стандартний приклад перевірки того, чи міститься елемент в масиві, з допомогою indexOf:

var numbers = [3, 5, 8, 11, 23, 7];

if (numbers.indexOf(1) !== -1) {
// ...
}


Використовуючи includes, те ж саме можна написати так:

var numbers = [3, 5, 8, 11, 23, 7];

if (numbers.includes(1)) {
// ...
}


Також при впровадженні цього методу були враховані деякі неочевидні особливості, помічені при роботі з indexOf. Щодо значень NaN поведінка цього методу відрізняється.

Розглянемо на прикладі:
var numbers = [3, 5, 8, 11, 23, 7, NaN];
if (numbers.indexOf(NaN) !== -1) {
// Цей код не виконається
}

if (numbers.includes(NaN)) {
// Цей код виконається
}


Таким чином, indexOf(NaN) завжди повертає -1, незалежно від того, міститься це значення в масиві, а includes(NaN) повертає true або false в залежності від того, є цей елементів в масиві чи ні.

Продуктивність

Оцінка продуктивності javascript методів не така вже очевидна вешь, так як по суті в різних браузерах одна і та ж функція може бути реалізована по-різному в залежності від мови, на якому написаний сам браузер. До того ж дуже багато залежить від комп'ютера, на якому робиться ця оцінка. Але, тим не менш, я спробував зробити невеликий аналіз.

Я створив масив з 10000 цілих позитивних чисел і використав для аналізу сайт jsbench.github.io
В обох випадках, для чистоти експерименту, був використаний один і той же масив. Оцінка проводилася в браузерах Chrome 53 і Firefox 48.

Chrome
includes indexOf
елемент
в середині масиву
8,361 ops/sec ±0.38% 31,296 ops/sec ±0.65%
елемент
на початку масиву
22,043,904 ops/sec ±1.89% 136,512,737 ops/sec ±2.06%
шуканого елемента
немає у масиві
4,018 ops/sec ±0.71% 95,221 ops/sec ±0.53%


Firefox
includes indexOf
елемент
в середині масиву
84,880 ops/sec ±0.59% 86,612 ops/sec ±1.35%
елемент
на початку масиву
34,087,623 ops/sec ±0.99% 33,196,839 ops/sec ±0.84%
шуканого елемента
немає у масиві
25,253 ops/sec ±2.75% 14,994 ops/sec ±1.16%


Виходить, що в Chrome indexOf завжди працює швидше, а в Firefox відчутної різниці практично немає (крім випадку, коли в масиві немає шуканого елемента). І поведінка нового методу в Firefox здається більш логічним, так як в загальному-то indexOf і includes за логікою повинні мати одну і ту ж обчислювальну складність.

Рядка
Аналогічний метод був доданий і для роботи з рядками починаючи з ECMAScript 2015. Раніше в Firefox у версіях з 18 по 39 цей метод існував під ім'ям contains, проте із-за проблем сумісності він був перейменований в includes().

На закінчення слід зазначити, що даний метод підтримується поки що не всіма браузерами.
Браузер Масив Рядок
Chrome 47 41
Firefox 43 40
IE немає немає
Opera 34 немає
Safari 9 9
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.