Как добавить новый метод в стандартный объект Array через prototype в JavaScript
Что проверяют
Понимаете ли вы прототипную цепочку и то, почему расширять встроенные объекты считается плохой практикой. Написать Array.prototype.x = function может каждый. Следом спрашивают: «А в продакшене вы бы так сделали?» и «Чем это грозит?»
Как отвечать
Покажите механику: все массивы наследуют от Array.prototype, поэтому метод, добавленный туда, появится у любого массива, включая созданные раньше. Внутри метода this указывает на массив, на котором его вызвали.
Правильная запись выглядит так:
Object.defineProperty:Object.defineProperty(Array.prototype, 'double', { value() { return this.map(x => x * 2); }, writable: true, configurable: true }). Флагenumerableпо умолчаниюfalse, так метод ведёт себя как встроенный;- обычная функция, не стрелочная: у стрелочной нет своего
this, и вместо массива вы получите внешний контекст; - проверка перед добавлением:
if (!Array.prototype.double), чтобы не затереть существующую реализацию; - TypeScript: без объявления
declare global { interface Array<T> { double(): T[] } }компилятор не увидит метод.
Затем назовите риски. Если метод с таким именем появится в стандарте, ваша версия его перекроет или сломает. Это уже случалось: из-за старой библиотеки, которая добавляла свой flatten, в стандарт метод вошёл под именем flat, а contains по той же причине стал includes. Второй риск: код, подключённый как библиотека, меняет поведение всего приложения.
Легитимный случай один: полифил стандартного метода для старых браузеров, и его обычно берут готовым из core-js. В остальных случаях лучше утилита double(arr) или класс class MyArray extends Array.
Где спотыкаются
Добавляют метод присваиванием. Свойство становится перечисляемым и вылезает в for...in по массиву, который кто-то всё ещё использует.
Пишут метод стрелочной функцией и не понимают, почему this оказался undefined или window.
Отвечают только «как», не сказав, почему в реальном проекте так делать не стоит. Интервьюер ждёт именно эту часть.