Как реализовать полифилл для Array.prototype.some с учетом callback и thisArg?
Что проверяют
Знаете ли вы, как метод устроен по спецификации, а не только что он «возвращает true, если хоть один подошёл». Интервьюер ждёт деталей: дырки в массиве, короткое замыкание, thisArg, проверка колбэка. Следом часто спрашивают, почему полифилл нельзя повесить простым присваиванием.
Как отвечать
Проговорите шаги так, как их описывает спецификация:
- приведение:
const O = Object(this), вызов наnullилиundefinedбросаетTypeError. Полифилл пишется черезfunction, не стрелкой, иначеthisне будет массивом; - длина: считывается один раз до цикла, поэтому элементы, добавленные колбэком во время обхода, не посещаются. По спецификации это
ToLength, в старых полифиллах встречаетсяO.length >>> 0; - проверка колбэка:
typeof callback !== "function"даётTypeErrorещё до цикла, даже для пустого массива; - обход: для
kот 0 доlenпроверяемk in O. Дырки разреженного массива пропускаются, а элемент, удалённый во время обхода, тоже не посетится; - вызов:
callback.call(thisArg, O[k], k, O). Результат приводится к булеву: вернули1или непустую строку, значит совпадение, и цикл сразу прерывается сtrue; - итог:
false, если ни один элемент не подошёл. Для пустого массива это всегдаfalse.
Установка через Object.defineProperty(Array.prototype, "some", { value: fn, writable: true, configurable: true }) и только если метода ещё нет. enumerable по умолчанию false, так метод не вылезет в for...in по массивам.
Упомяните, что стрелочный колбэк игнорирует thisArg: у стрелки лексический this, и call его не меняет.
Где спотыкаются
Пишут Array.prototype.some = function () {...}. Свойство становится перечисляемым, и любой for...in по массиву где-то в коде начинает обходить some как элемент.
Не проверяют k in O и вызывают колбэк на дырках со значением undefined. Для [, , 1].some(x => x === undefined) такой полифилл вернёт true, а нативный метод false.
Не прерывают цикл после первого совпадения или сравнивают результат строго с true. Колбэк, который возвращает найденный объект, тогда считается неудачей, хотя по спецификации любое истинное значение означает успех.