Общие причины не иметь дело с прототипом Document и Element - PullRequest
9 голосов
/ 30 сентября 2010

Существуют ли общие причины не иметь дело с прототипом Document и Element?

Мне нравится создавать собственную небольшую платформу, потому что моему текущему проекту не требуется масса функций существующих платформ.

Мне не нужно поддерживать браузеры, которые не поддерживают Element / Document-конструктор, а также не будут выполнять скрипты, которые не находятся под моим контролем.

Поэтому вы бы порекомендовали расширить прототипя должен идти обычным путем и создавать собственные объекты из элемента / документа?

Ответы [ 2 ]

8 голосов
/ 30 сентября 2010

Планируете ли вы расширить элементы DOM по умолчанию? Если так, пожалуйста, не надо. Юрий Зайцев (он же Кангакс) четко описывает почему не в Что плохого в расширении DOM .

6 голосов
/ 30 сентября 2010

Да, к сожалению. Было бы замечательно иметь возможность добавить функциональность, возясь с прототипами DOM, но на практике это просто ненадежно, учитывая современные технологии.

Document, Element и другие и т. Д. Могут быть «хост-объектами», реализованными браузером без возможности манипулировать своими прототипами. Хост-объекты могут потенциально иметь много других странных поведений, которых не было бы у нативного объекта JavaScript. Узлы DOM являются хост-объектами в IE6-7 и во многих старых, нишевых и мобильных браузерах.

Даже если они реализованы как объекты нативного JavaScript, нет никакого стандарта (пока), который описывал, где должна быть найдена функция-конструктор для них, чтобы вы могли ловить рыбу в .prototype. Document, Element и так далее - это просто имена интерфейсов W3 DOM, они ничего не говорят о том, какие объекты реализации нужно найти.

Бывает, что современные браузеры (собственный режим IE8 и последние версии Firefox, Opera и WebKit) делают функции-конструкторы доступными, поэтому вы можете начать добавлять методы в Document или HTMLElement. Но даже в этом случае существуют различия между объектами, которые предоставляются, поскольку не каждый браузер предоставляет интерфейсам DOM реализации с одинаковыми именами. (Подынтерфейсы / реализации NodeList особенно проблематичны.)

Вы можете увидеть, как прототипирование DOM работало на практике, посмотрев каркас Prototype.js. Когда это работает, это супер гладко. Но поскольку вы не можете создавать прототипы повсюду, у вас получаются очень уродливые вещи, где фреймворк должен иметь дело с местами, где прототипирование не будет работать, копируя методы в каждый экземпляр узла. И тогда у вас возникает ситуация, когда ваш код может забыть, что он должен форсировать это «расширение», и поэтому он может работать или не работать в зависимости от того, случалось ли, что какая-то другая функция ранее добавляла этот же узел. Это приводит к действительно ужасной отладочной боли, специфичной для браузера, порядка взаимодействия, склонной к гоночным состояниям.

Если вы можете ограничить свою работу по созданию прототипов несколькими хорошо поддерживаемыми интерфейсами и отказаться от всех браузеров, кроме самых последних, вы, вероятно, сойдете с рук.

...