Estou procurando uma resposta definitiva para o motivo pelo qual a extensão de protótipos internos é tão fortemente castigada na comunidade de desenvolvedores de JS. Eu uso o framework JS Prototype há um tempo, e para mim isso [1,2,3].each(doStuff)
parece muito mais elegante do que $.each([1,2,3], doStuff)
. Sei que isso cria "poluição no espaço de nome", mas ainda não entendo por que isso é considerado uma coisa ruim. Também existe alguma degradação real do desempenho associada à extensão de protótipos internos? Obrigado!
15
for(var ... in ...)
loops ficam confusos, pois as funções do protótipo também são passadas.Respostas:
Eu sugiro que você leia este artigo, o que eu acho que explica muito bem por que estender objetos é uma má idéia, com relação ao Prototype também.
Em suma:
Falta de especificação
Objetos host não têm regras
Possibilidade de colisões
Sobrecarga de desempenho
IE DOM está uma bagunça
Bônus: bugs no navegador
fonte
Outro motivo é a legibilidade / manutenção do código. Se outro desenvolvedor (especialmente um novato) estiver lendo meu código e vir
[0, 1, 2].foo(...)
, ele pode não saber qual é o método foo ou onde encontrar documentação / fonte para ele. Foo é uma extensão do idioma adicionada por prototype.js ou por outra biblioteca em uso, ou por alguma outra parte do meu código em outro arquivo, ou é um método JavaScript nativo que eles desconheciam? Eles precisam procurá-lo e podem não encontrá-lo imediatamente (ou, se houver conflitos, podem não encontrar o caminho certo).Com a abordagem jQuery, se você vir
$.foo(...)
, o espaço para nome do método foo torna óbvio onde encontrar sua definição / documentação se você não souber o que faz.fonte
Aqui está o problema básico: o que acontece se você tiver duas ferramentas que estendem protótipos de maneiras incompatíveis ou que estendem métodos comumente chamados de maneiras a produzir resultados diferentes (esse é um problema específico do
for...in
JavaScript), causando código que depende em seu comportamento normal para quebrar?Basicamente, são os mesmos problemas que você tem ao usar mal as variáveis globais. Por si só, talvez nada de ruim aconteça. Mas isso abre problemas quando dois códigos ostensivamente separados subitamente se interagem (e é difícil debugar quando isso acontece).
Certamente prototype.js é bastante conhecido e a maioria das ferramentas trabalha em torno do que faz. Da mesma forma, tenho certeza de que há casos em que estender protótipos de base é a coisa certa a fazer. Mas, é algo para abordar com cautela.
fonte
Não tenho certeza se isso ainda é realmente um problema, mas minha experiência com versões anteriores do Internet Explorer é que às vezes nem era possível estender certos tipos de build.
fonte
Existem duas questões separadas aqui. O primeiro é a extensão geral de protótipos internos, e o outro é a extensão específica de protótipos DOM. Os argumentos contra a extensão de protótipos internos:
Array.prototype
ouObject.prototype
pode ter efeitos indiretos, como adicionar os métodos de extensão que estão sendo enumerados em umfor...in
loopQuanto à extensão dos protótipos do DOM, o potencial argumento de conflito acima ainda se aplica. Além disso, os nós DOM são objetos de host e, como tal, não estão sujeitos a nenhuma das regras normais de objetos JavaScript nativos. Eles podem essencialmente fazer o que quiserem e não têm obrigação de fornecer objetos protótipos sensíveis ou até mesmo permitir propriedades extras ("expando"). O IE, em particular, exerce esse direito, não fornecendo protótipos para objetos DOM antes do IE 9 e tendo várias estranhezas sobre propriedades em vários objetos DOM (embora você geralmente esteja bem atribuindo propriedades a elementos, desde que nada esteja definido
document.expando
comofalse
).fonte