JS вполне себе динамический язык, позволяющий многое, но некоторыми вещами стоит пользоваться с осторожностью, чтобы потом не было мучительно больно это отлаживать.
Нужные методы можно подменить, просто перезаписав в них новые функции, но лучше делать это не глобально для всех массивов на прототипе, а на конкретном инстансе массива, например так:
const arr = []; // создали массив
arr.push = function() { // перезаписываем конкретно его push
Array.prototype.push.apply(this, arguments); // вызвали оригинальный push со всеми аргументами
// тут делаем еще что-то
};
Еще что-то может производить неожиданный эффект, который впоследствии доставит боли при дебаге такого кода, поэтому как рекомендовали выше, лучше пользоваться декоратором, но метод вполне рабочий, и используется например в vue.js для отслеживания изменений в массивах