Я встретил несколько комментариев здесь и там о том, как он нахмурился, чтобы изменить прототип объекта JavaScript? Я лично не вижу, как это может быть проблемой. Например, расширение объекта Array на использование методов карты и включения или создание более надежных методов Date?
Почему он недоволен изменением прототипов объектов JavaScript?
Ответ 1
Проблема заключается в том, что прототип можно модифицировать в нескольких местах. Например, одна библиотека добавит метод карты в прототип Array, и ваш собственный код добавит то же самое, но с другой целью. Таким образом, одна реализация будет нарушена.
Ответ 2
В основном из-за конфликтов пространства имен. Я знаю, что в структуре Prototype было много проблем с сохранением их имен, отличных от тех, которые были включены изначально.
Существуют два основных метода предоставления коммунальных услуг людям.
прототипирования
Добавление функции в прототип объекта. MooTools и Prototype делают это.
Преимущества:
- Супер легкий доступ.
Недостатки:
- Может использовать много системной памяти. В то время как современные браузеры просто извлекают экземпляр свойства из конструктора, некоторые старые браузеры хранят отдельный экземпляр каждого свойства для каждого экземпляра конструктора.
- Не обязательно всегда доступно.
Что я подразумеваю под "недоступным", это:
Представьте, что у вас есть NodeList из document.getElementsByTagName
, и вы хотите итерации через них. Вы не можете делать.
document.getElementsByTagName('p').map(function () { ... });
.. потому что это NodeList, а не массив. Вышеприведенное приведет к ошибке: Uncaught TypeError: [object NodeList] doesn't have method 'map'
.
Я должен отметить, что есть очень простые способы конвертировать NodeList и другие Array-подобные Объекты в реальные массивы.
Сбор
Создание на нем новой глобальной переменной и утилиты для укладки штабелей. jQuery и Dojo сделать это.
Преимущества:
- Всегда там.
- Низкое использование памяти.
Недостатки:
- Не помещено так же хорошо.
- Может быть неудобно использовать время от времени.
С помощью этого метода вы все равно не можете этого сделать.
document.getElementsByTagName('p').map(function () { ... });
.. но вы могли бы сделать.
jQuery.map(document.getElementsByTagName('p'), function () { ... });
.. но, как указал Мэтт, при обычном использовании вы делали бы это выше с помощью.
jQuery('p').map(function () { ... });
Что лучше?
В конечном счете, это зависит от вас. Если вы в порядке с риском перезаписывания/перезаписи, я бы настоятельно рекомендовал прототипирование. Это стиль, который я предпочитаю, и я чувствую, что риски стоят результатов. Если вы не так уверены в этом, как я, то сбор тоже прекрасный стиль. У них обоих есть преимущества и недостатки, но все они, как правило, дают одинаковый конечный результат.
Ответ 3
Как отметил Бьорнд, обезвреживание обезьян является проблемой только при наличии нескольких библиотек. Поэтому это не очень хорошая практика, если вы пишете библиотеки многократного использования. Тем не менее, он по-прежнему остается лучшей технологией для устранения проблем с совместимостью между браузерами при использовании объектов хоста в javascript.
Смотрите эту ссылку для реальной аварии, когда prototype.js и json2.js используются вместе.
Ответ 4
Существует замечательная статья Николаса К. Закаса, объясняющая, почему эта практика не является чем-то, что должно быть в уме любого программиста во время проекта команды или клиента (возможно, вы можете сделать некоторые настройки в образовательных целях, но не для общих использование проекта).
Поддерживаемый JavaScript: не изменяйте объекты, которые у вас нет: https://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
Ответ 5
В дополнение к другим ответам, еще более постоянная проблема, которая может возникнуть из-за изменения встроенных объектов, заключается в том, что если нестандартное изменение будет использоваться на достаточном количестве сайтов, будущие версии ECMAScript не смогут определять методы-прототипы с тем же именем, Смотрите здесь:
Это именно то, что произошло с
Array.prototype.flatten
иArray.prototype.contains
. Короче говоря, для этих методов была составлена спецификация, их предложения дошли до стадии 3, а затем браузеры начали ее отправку. Но в обоих случаях было обнаружено, что существуют древние библиотеки, которые исправляли встроенный объектArray
своими собственными методами с тем же именем, что и новые методы, и имели другое поведение; в результате веб-сайты сломались, браузерам пришлось отказаться от реализации новых методов, а спецификацию пришлось редактировать. (Методы были переименованы.)
Например, в настоящее время есть предложение для String.prototype.replaceAll. Если вы отправляете библиотеку, которая становится широко используемой, и эта библиотека монтирует нестандартный метод в String.prototype.replaceAll
, имя replaceAll
больше не будет использоваться авторами спецификаций; это должно быть изменено прежде, чем браузеры смогут реализовать это.