Я ищу окончательный ответ на вопрос, почему расширение встроенных прототипов так жестко наказывается в сообществе разработчиков JS. Я уже давно использую Prototype JS Framework, и мне [1,2,3].each(doStuff)
кажется, что делать это гораздо элегантнее $.each([1,2,3], doStuff)
. Я знаю, что это создает «загрязнение пространства имен», но я все еще не понимаю, почему это считается плохой вещью. Также существует ли реальное снижение производительности, связанное с расширением встроенных прототипов? Благодарность!
15
for(var ... in ...)
циклы перепутаны, так как функции прототипа также передаются.Ответы:
Я предлагаю вам прочитать эту статью, которая, я думаю, довольно хорошо объясняет, почему расширение объектов является плохой идеей, в том числе и в отношении Prototype.
В итоге:
Отсутствие спецификации
Хост-объекты не имеют правил
Возможны столкновения
Накладные расходы
IE DOM беспорядок
Бонус: ошибки браузера
источник
Другой причиной является удобочитаемость кода. Если другой разработчик (особенно новичок) читает мой код и видит
[0, 1, 2].foo(...)
, они могут не знать, что такое метод foo или где найти документацию / источник для него. Является ли foo расширением языка, добавленного prototype.js, или другой используемой библиотекой, или какой-то другой частью моего кода в другом файле, или это родной метод JavaScript, о котором они не знали? Они должны охотиться за ним и могут не найти его сразу (или, если есть конфликты, они могут не найти правильный).С подходом jQuery, если вы видите
$.foo(...)
, пространство имен метода foo делает очевидным, где найти его определение / документацию, если вы не знаете, что он делает.источник
Вот основная проблема: что произойдет, если у вас есть два инструмента, которые расширяют прототипы несовместимыми способами, или которые расширяют обычно вызываемые методы таким образом, чтобы они давали разные результаты (это особая проблема для
for...in
JavaScript), таким образом вызывая код, который полагается от их нормального поведения нарушать?По сути, это те же проблемы, которые возникают при неправильном использовании глобальных переменных. Само собой, возможно, ничего плохого не происходит. Но это открывает для вас проблемы, когда два якобы отдельных куска кода неожиданно сталкиваются друг с другом (и это затрудняет отладку, когда это происходит).
Конечно, prototype.js довольно хорошо известен, и большинство инструментов работают вокруг того, что он делает. Точно так же я уверен, что есть случаи, когда расширение базовых прототипов является правильным решением. Но к этому нужно подходить с осторожностью.
источник
Не уверен, что это действительно все еще проблема, но мой опыт работы с более ранними версиями Internet Explorer заключается в том, что иногда даже невозможно расширить некоторые встроенные типы.
источник
Здесь есть два отдельных вопроса. Первый - это общее расширение встроенных прототипов, а второй - расширение DOM-прототипов. Аргументы против расширения встроенных прототипов:
Array.prototype
илиObject.prototype
может вызывать эффекты, такие как добавление методов расширения, перечисляемых вfor...in
циклеЧто касается расширения прототипов DOM, то приведенный выше аргумент потенциального конфликта все еще применяется. Кроме того, узлы DOM являются хост-объектами и, как таковые, не подпадают под действие каких-либо нормальных правил собственных объектов JavaScript. По сути, они могут делать то, что им нравится, и не обязаны предоставлять разумные объекты-прототипы или даже разрешать дополнительные ("расширенные") свойства. IE , в частности , упражнения этого права, не предоставляя прототипов DOM объектов , прежде чем IE 9 и имеющий различные weirdnesses о свойствах на различных объектах DOM (хотя вы обычно OK Назначение свойства элементов, при условии , набора Ничего
document.expando
кfalse
.)источник