Как получить элемент массива по индексу в реализации some?
Что проверяют
Знаете ли вы, как some устроен по спецификации, а не только как им пользоваться. Цикл с return true пишут все, поэтому следом спрашивают про дырявые массивы, thisArg и про то, что будет, если массив меняется во время обхода.
Как отвечать
Внутри метода массив доступен как this, значит текущий элемент берётся обычным доступом по ключу, O[i]. Колбэк получает три аргумента, как во встроенном методе: callback.call(thisArg, O[i], i, O). Дальше назовите детали, которые отличают полифил от наивного цикла:
- длина фиксируется один раз:
lenчитается до цикла, элементы, добавленные колбэком, обход не увидит; - дыры пропускаются: перед чтением проверяется
i in O, поэтому для[, 1]колбэк вызовется один раз, а удалённые по ходу элементы не посетятся; - проверка колбэка: не функция даёт
TypeError, причём даже на пустом массиве; - приведение результата: колбэк может вернуть что угодно, метод возвращает строго
trueилиfalse; - ранний выход: обход прекращается на первом истинном результате, пустой массив даёт
false.
Object.defineProperty(Array.prototype, 'mySome', {
value: function (callback, thisArg) {
const O = Object(this);
const len = O.length >>> 0;
if (typeof callback !== 'function') throw new TypeError();
for (let i = 0; i < len; i++) {
if (i in O && callback.call(thisArg, O[i], i, O)) return true;
}
return false;
},
writable: true,
configurable: true,
});Благодаря Object(this) метод работает и с псевдомассивами: Array.prototype.mySome.call(arguments, fn).
Где спотыкаются
Пишут метод стрелочной функцией. У стрелки нет своего this, и вместо массива внутри оказывается внешний контекст.
Берут forEach и пишут return true внутри колбэка. Этот return выходит только из колбэка, обход не прерывается, а внешняя функция возвращает undefined.
Не проверяют i in O. Тогда [, 1].mySome(x => x === undefined) вернёт true, хотя встроенный some на том же массиве вернёт false.