Estoy buscando una respuesta definitiva a por qué la extensión de los prototipos incorporados está tan castigada en la comunidad de desarrolladores de JS. He estado usando el marco Prototype JS por un tiempo, y para mí [1,2,3].each(doStuff)
parece mucho más elegante que eso $.each([1,2,3], doStuff)
. Sé que crea "contaminación del espacio de nombres", pero todavía no entiendo por qué se considera algo malo. ¿También hay alguna degradación real del rendimiento asociada con la extensión de los prototipos integrados? ¡Gracias!
15
for(var ... in ...)
bucles se estropean ya que las funciones prototipo también se pasan.Respuestas:
Le sugiero que lea este artículo que creo que explica bastante bien por qué extender objetos es una mala idea, también con respecto a Prototype.
En resumen:
Falta de especificación
Los objetos host no tienen reglas
Posibilidad de colisiones
Sobrecarga de rendimiento
IE DOM es un desastre
Bonus: errores del navegador
fuente
Otra razón es la legibilidad / mantenibilidad del código. Si otro desarrollador (especialmente un novato) está leyendo mi código y ve
[0, 1, 2].foo(...)
, es posible que no sepan cuál es el método foo o dónde encontrar documentación / fuente. ¿Es foo una extensión del lenguaje agregado por prototype.js, o por otra biblioteca en uso, o por alguna otra parte de mi código en otro archivo, o es un método nativo de JavaScript que no sabían? Necesitan buscarlo y es posible que no lo encuentren de inmediato (o si hay conflictos, es posible que no encuentren el correcto).Con el enfoque jQuery, si ve
$.foo(...)
, el espacio de nombres del método foo hace obvio dónde encontrar su definición / documentación si no sabe lo que hace.fuente
Aquí está el problema básico: qué sucede si tiene dos herramientas que extienden prototipos de manera incompatible, o que extienden métodos comúnmente llamados de manera tal que producen resultados diferentes (este es un problema particular para
for...in
JavaScript), causando código que depende en su comportamiento normal para romper?Básicamente, son los mismos problemas que tiene cuando usa mal las variables globales. Por sí mismo, tal vez no pase nada malo. Pero, te abre problemas cuando dos partes de código aparentemente separadas se pisan repentinamente (y es una tarea difícil de depurar cuando eso sucede).
Ciertamente, prototype.js es bastante conocido y la mayoría de las herramientas funcionan en torno a lo que hace. Del mismo modo, estoy seguro de que hay casos en los que extender prototipos base es lo correcto. Pero, es algo para abordar con precaución.
fuente
No estoy seguro de si esto sigue siendo un problema, pero mi experiencia con versiones anteriores de Internet Explorer es que a veces ni siquiera era posible extender ciertos tipos integrados.
fuente
Hay dos problemas separados aquí. El primero es la extensión general de los prototipos incorporados, y el otro es específicamente extender los prototipos DOM. Los argumentos en contra de extender los prototipos incorporados:
Array.prototype
oObject.prototype
puede tener efectos secundarios, como agregar los métodos de extensión que se enumeran en unfor...in
bucleEn cuanto a la extensión de los prototipos DOM, el argumento de conflicto potencial anterior aún se aplica. Además, los nodos DOM son objetos host y, como tales, no están sujetos a ninguna de las reglas normales de los objetos JavaScript nativos. Básicamente, pueden hacer lo que quieran y no tienen la obligación de proporcionar objetos prototipo sensibles o incluso permitir propiedades adicionales ("expando"). IE en ejercicios particulares de este derecho, siempre y cuando no prototipos de objetos DOM antes de IE 9 y que tiene varios weirdnesses acerca de las propiedades de varios objetos DOM (aunque estás propiedades Asignación general OK a elementos, siempre conjunto de nada
document.expando
afalse
.)fuente