#javascript #jquery #arrays #object #prototype
#javascript #jquery #массивы #объект #прототип
Вопрос:
Я хочу расширить массив и объект следующим образом:
$(window).load(function() {
Array.prototype.x = 3
Object.prototype.y = 4
var a = [1, 2]
for (var i in a) {
alert(i ': ' a[i])
}
})
/*
[result]
0: 1
1: 2
x: 3
y: 4
*/
Вызовет ли этот код какие-либо проблемы с работой jQuery в текущей или будущей версии jQuery?
Комментарии:
1. Если вы ожидаете, что свойства будут возвращены в определенном порядке, вы можете быть разочарованы некоторыми широко используемыми браузерами.
2. Кроме того, jQuery выполняет незащищенные for..in итерация во многих местах, поэтому расширение Object.prototype будет вызывать проблемы.
Ответ №1:
С Array.prototype
, я думаю, вы в полной безопасности. Я не думаю, что где-либо есть явная гарантия, но jQuery годами сосуществует на сайтах с Prototype и MooTools, и они оба расширяют Array.prototype
. Я не думаю, что команда jQuery захотела бы нарушить совместимость с этими библиотеками.
Но: Никогда не расширяйте Object.prototype
. Это вполне может нарушить собственный код jQuery и почти наверняка также нарушит код подключаемого модуля. Большинство for..in
циклов предполагают, что {}
они не будут иметь перечислимых свойств. Если вы добавляете в Object.prototype
, вы делаете это предположение недействительным. (Если только вы не используете новую функцию ECMAScript5 defineProperty
, которая позволяет вам сделать свойства неисчислимыми, но она пока не получила широкой поддержки. Впрочем, для развлечения вы можете попробовать это здесь.)
Комментарии:
1. большое вам спасибо. ваш ответ очень полезен. я использую
defineProperty
для своего программного обеспечения и расширяю обаArray
иObject
сdefineProperty
без беспокойства. (меня не волнует, что некоторые браузеры не поддерживаютdefineProperty
)2. @js_: Рад, что помогло! Неприятно говорить вам, что не некоторые браузеры (пока) не поддерживают его, это браузеры, используемые в настоящее время подавляющим большинством людей — смотрите эту статистику и это . Firefox не поддерживал его до FF4, IE не поддерживал его (для вашего варианта использования) до IE9 (IE8 имел очень ограниченную поддержку для него, связанную с узлами DOM)… Итак, в скором времени пользователи Firefox получат его (они обновляются рано), но пользователи IE … вздыхают 😉
3. спасибо за ваш комментарий. мне очень грустно это слышать. я действительно хочу, чтобы как можно больше людей пользовались моим программным обеспечением. но я хочу свободно писать коды, которые я хочу написать. и я устал поддерживать ie. я надеюсь, что 25% людей (которые используют chrome и скоро будут использовать ff4) достаточно много.
4. @js_: Удачи с этим. Я бы сказал, что расширение
Object.prototype
— это действительно большая проблема. Не могли бы вы создать свой собственный тип базового объекта и добавить свойства к его прототипу?5. спасибо за ваш совет. я думаю, что это сложно, потому что я планирую добавить несколько функций для работы с Object object, например, функцию клонирования объекта, повторяющуюся функцию, такую как jQuery.each, функцию для подсчета свойств объекта и т.д.
Ответ №2:
Нет, насколько мне известно, таких гарантий от jQuery нет.
Сам jQuery не расширяет какие-либо собственные прототипы, поэтому он в значительной степени самодостаточен, за исключением некоторого ограниченного изменения узлов DOM. Однако вы не можете полагаться на плагины jQuery, написанные другими, которые также будут вести себя хорошо при расширении Array
и Object
подобным образом. Многие другие библиотеки действительно расширяются Array
, но расширение Object
имеет более серьезные последствия, поскольку оно затрагивает каждый отдельный объект.
Будет ли это работать со всеми будущими версиями jQuery? Попробуйте угадать 🙂
Ответ №3:
Джон Ресиг (создатель jQuery) однажды написал, что jQuery безопасен против расширения Array.prototype, но не на 100% безопасен против расширения Object.prototype (я не помню точное место, вероятно, это было в анонсе новой версии jQuery). Формальной гарантии нет, AFAIK, но целью jQuery является устойчивость к таким изменениям и проблемам, расширенные прототипы (такие как this или this) обрабатываются как ошибки, хотя, как вы можете видеть из примеров, на их исправление может потребоваться некоторое время, поэтому, даже расширяя Array, вы несколько повышаете риск возникновения ошибки.