Большой красный флаг: никогда расширить Object.prototype
! Это ломает for (x in y)
(или, по крайней мере, ожидания людей о том, как это работает).
Однако в общем случае лучше расширять прототипы отдельных типов, а не пытаться найти общую базу и выполнять проверки отражения. Для этого есть две основные причины.
Во-первых, JavaScript - это язык с динамической типизацией, поэтому вы, как правило, предпочитаете утиную типизацию и базовое наследование, а не instanceof
и рефлексию. Во многих случаях производительность невелика, но в основном это так, что вы не тратите время на борьбу с языком.
Во-вторых, этот тип переключения методов подразумевает соединения между коммутируемыми методами, которые не обязательно существуют. В вашем примере кода это можно увидеть в версии NodeList
. Концептуально список не должен связывать ничего; если у него есть метод bind
, он должен просто переводить вызов метода bind
для каждого из его элементов. Это гарантирует, что если в будущем потребуется добавить какие-либо дополнительные шаги для привязки (скажем, обходные пути для старых, не соответствующих DOM-браузерам…), вам нужно будет сделать это только в одном месте.
Но если посмотреть на это с точки зрения переключения типов в «одной и той же функции», создается ложное впечатление, что и Element.bind
, и NodeList.bind
должны работать одинаково - вызывая addEventListener
. Вот как я бы это реализовал:
Element.prototype.bind = function(eventType, fn) {
this.addEventListener(eventType, fn, false);
};
NodeList.prototype.bind = function(eventType, fn) {
for (var i = 0, l = this.length; i < l; i++) {
this[i].bind(eventType, fn);
}
};