Подтвердить что ты не робот

Почему он недоволен изменением прототипов объектов JavaScript?

Я встретил несколько комментариев здесь и там о том, как он нахмурился, чтобы изменить прототип объекта JavaScript? Я лично не вижу, как это может быть проблемой. Например, расширение объекта Array на использование методов карты и включения или создание более надежных методов Date?

4b9b3361

Ответ 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 больше не будет использоваться авторами спецификаций; это должно быть изменено прежде, чем браузеры смогут реализовать это.