2016-07-15 4 views
0

Я много обсуждал вопрос о расширении Element. Насколько я могу судить, это основные вопросы:JavaScript: расширенный элементный прототип

  • Это может конфликтовать с другими библиотеками
  • Он добавляет недокументированные функции в DOM подпрограммы
  • Он не работает с унаследованным IE
  • It могут вступать в конфликт с будущим изменения

Учитывая проект, который не ссылается никакие другие библиотеки, документы изменения, и не дает ни черта исторических браузеров:

Есть ли технические причина не продлевать прототип элемента. Вот пример того, как это полезно:

Element.prototype.toggleAttribute=function(attribute,value) { 
    if(value===undefined) value=true; 
    if(this.hasAttribute(attribute)) this.removeAttribute(attribute); 
    else this.addAttribute(attribute,value); 
}; 

Я видел слишком много комментариев о зле расширения прототипов, не предлагая разумное объяснение.

Примечание 1: приведенный выше пример, возможно, слишком очевиден, так как toggleAttribute - это способ, который может быть добавлен в будущем. Для обсуждения предположите, что это называется manngoToggleAttribute.

Примечание 2: Я удалил тест на то, существует ли метод уже существует. Даже если такой метод уже существует, более предсказуемо его переопределить. В любом случае, Я предполагаю, что дело здесь в том, что метод еще не определен, не говоря уже о реализации. Вот в чем дело.

Thanks

+3

У вас также может возникнуть проблема с прямой совместимостью - функция, которую вы добавляете, может стать частью стандарта в будущем. – Timo

+1

Что именно вы подразумеваете под «технической причиной»? Нет, расширение «Элемента» (как вы выяснили) отлично работает в контролируемых средах. – Bergi

+0

@TimoSta Я изменил образец кода, чтобы включить тест. – Manngo

ответ

0

Не изменяйте объекты, которые у вас нет.

Представьте, что будущий стандарт определяет Element.prototype.toggleAttribute. Ваш код проверяет, имеет ли он правдивое значение перед назначением вашей функции. Таким образом, вы можете в конечном итоге с будущей нативной функцией, которая может вести себя иначе, чем вы ожидали.

Более того, просто чтение Element.prototype.toggleAttribute может называть геттер, который может запускать некоторый код с нежелательными побочными эффектами. Например, посмотрите, что произойдет, когда вы получите Element.prototype.id.

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

Вы можете использовать определение свойства вместо назначения свойства. Это должно быть безопаснее ... если у Element.prototype есть специальный метод [[DefineOwnProperty]] (например, это прокси).

Это может потерпеть неудачу множеством способов. Не делай этого.

+0

так что, если это произойдет? –

+0

@BekimBacaj Если он что-то делает? – Oriol

+0

, пожалуйста, см. Мой полный ответ на эту тему в комментариях к Ops. –

-1

Есть ли какая-либо техническая причина не продлевать прототип элемента.

Абсолютно нет!

pardon me: АБСОЛЮТНО НЕТ!

Кроме того, .__proto__ был практически незаконным продлением прототипа до вчерашнего дня. - Сегодня это стандарт.


p.s .: Вы должны избегать использования if(!Element.prototype.toggleAttribute) синтаксиса любых средств, то если ("toggleAttribute" в Element.prototype) будет делать.

+1

Как вы можете быть уверены? У вас есть источники? Какие именно предположения, ограничения, которые могут быть нарушены, приведут к отказу кода? – Bergi

+0

Попробуйте «расширить» 'Element.prototype' новым свойством' id'. 'if (Element.prototype.id)' бросает. 'Element.prototype.id = 123' бросает. Точно так же добавление 'toggleAttribute' не является надежным для будущего. – Oriol

+0

@ Bergi yes У меня есть - мой опыт работы с приложениями JavaScript распространяется и, вероятно, превышает ваш возраст. И я не предполагал ни одной из этих вещей. Код сам по себе не сработает. –

1

В порядке? Технически да. Должны ли вы распространять собственные API? Как правило, нет. К сожалению, ответ более сложный. Если вы пишете большую структуру, такую ​​как Ember или Angular, это может быть хорошей идеей сделать это, потому что ваши потребители будут иметь Benifits, если они лучше подходят для API. Но если вы делаете это только для себя, то эмпирическое правило - нет.

Причина в том, что это дестабилизирует доверие к этому объекту. Другими словами, добавляя, изменяя, изменяя собственный объект, он больше не следует хорошо понятому и документированному поведению, которое ожидает любой другой (включая ваше будущее).

Этот стиль скрывает реализацию, которая может остаться незамеченной. Что это за новый метод?, Это секретная вещь браузера?, Что делать?, Нашли ошибку, сообщите об этом Google или Microsoft сейчас?. Немного преувеличено, но дело в том, что правда API теперь изменилась, и это неожиданно в этом случае. Это заставляет ремонтопригодность нуждаться в дополнительной мысли и понимания, которая бы не была такой, если бы вы просто использовали свою собственную функцию или объект-оболочку. Это также делает изменения сложнее.

Соответствующее сообщение: Extending builtin natives. Evil or not?

Вместо того, чтобы пытаться сбросить кого-то (или стандартный) код еще раз использовать свои собственные.

function toggleAttribute(el, attribute, value) { 
    var _value = (value == null ? true : value; 
    if (el.hasAttribute(attribute)) { 
    el.removeAttribute(attribute); 
    } else { 
    el.addAttribute(attribute, _value); 
    } 
}; 

Теперь это безопасно, удобно, удобно и удобно. Кроме того, другие разработчики (в том числе и ваше будущие «я») не будут сбивать с толку головоломки, если бы этот магический метод, который не документирован ни в одном стандарте, ни в JS API.

+0

ОП задал вопрос, следует ли и почему он не должен распространять прототип 'Element'. Он не просил разрешения, которое его не продлевало. – destoryer

+1

Черт возьми, мне очень жаль, я не должен был отвечать! О, это ужасно. Я чувствую себя ужасно. Я не буду спать уже несколько дней :( – Sukima

+1

Вы не должны комментировать. – destoryer

Смежные вопросы