Objeto de Extensión.prototipo de JavaScript


No estoy preguntando si esto está bien:

Object.prototype.method = function(){};

Esto es considerado malvado por casi todo el mundo, considerando que arruina for(var i in obj).

La Verdadera Pregunta

Ignorando

  • Navegadores incompetentes (navegadores que no son compatibles con Object.defineProperty)
  • Potencial de colisión o sobreescritura de propiedades

Asumiendo que tienes algún increíblemente método útil, ¿se considera esto incorrecto/poco ético?

Object.defineProperty(Object.prototype, 'methodOnSteriods',{
  value: function(){ /* Makes breakfast, solves world peace, takes out trash */ },
  writable: true,
  configurable: true,
  enumerable: false
});

Si cree que lo anterior es poco ético, ¿por qué implementarían la característica en primer lugar?

Author: maja, 2011-07-29

5 answers

Creo que está bien si funciona en su entorno objetivo.

También creo que la paranoia de extensión de prototipo es exagerada. Mientras uses hasOwnProperty() como un buen desarrollador, todo está bien. En el peor de los casos, sobrecarga esa propiedad en otro lugar y pierde el método. Pero es tu culpa si haces eso.

 23
Author: Alex Wayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-29 18:00:40

Yo diría que esto es casi tan malvado como antes. El mayor problema, sigue siendo el mismo que antes, es que Objeto.el prototipo es global . Si bien su método actualmente podría estar resolviendo la paz mundial, podría haber sobrescrito el método de otra persona (que garantizaba la paz galáctica) o puede ser sobrescrito en el futuro por alguna biblioteca sobre la que no tiene control (por lo tanto, sumergiendo al mundo en el caos nuevamente)


Las nuevas versiones de Javascript tienen muchas características relacionadas con propiedades, como definig una propiedad para ser enumerable / no enumerable, con getters y setters... Objeto.Definepropiedad existes para dar el control sobre esto.

De Mozilla Docs :

Este método permite la adición o modificación precisa de una propiedad en un objeto. La adición normal de propiedades a través de la asignación crea propiedades que aparecen durante la enumeración de propiedades (for...in bucle), cuyos valores pueden cambiarse y que pueden eliminarse. Este método permite que estos detalles adicionales se cambien de sus valores predeterminados.


Esta nueva función es básicamente necesaria para soportar las nuevas características y se supone que debes usarla en tus propias cosas. Ser capaz de modificar el Objeto.prototipo es solo un efecto secundario de que también es un objeto "normal" y es tan malo como antes.

 8
Author: hugomg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-02 08:27:42

Bueno en "JavaScript: las partes buenas", hay una función similar, creo que es muy útil para mejorar los objetos base de javascript (como String, Date, etc..), pero solo por eso.

// Add a method conditionally. from "JavaScript: the good parts"

Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
}
 3
Author: sacabuche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-29 18:29:44

.hasOwnProperty() excluirá la iteración a través de propiedades heredadas, que personalmente encuentro que a menudo es más molesto que útil. En gran medida derrota la utilidad de Object.create(), lo cual es irónico ya que el mismo tipo que convenció a todos a hacer .hasOwnProperty() también promovió Object.create().

Objeto.el prototipo no debe ampliarse, por las razones enumeradas aquí. Si realmente quieres extenderlo, haz que las extensiones no sean iterables.

Me doy cuenta de que esto va en contra de todos los publicados mejores prácticas, pero realmente deberíamos dejar de" exigir " .hasOwnProperty() en iteraciones de clave de objeto y adoptar la utilidad de la herencia directa de objeto a objeto.

 3
Author: Nomad128,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-15 21:48:28

La respuesta corta es Sí, deberías hacerlo.

Antes de hacerlo, hay que tomar varias precauciones:
1. usar hasOwnProperty al iterar un objeto, pero esto no es realmente una precaución, al iterar un objeto, ya estoy usando hasOwnProperty de todos modos.
2. compruebe si el name en Object.prototype.name ha existido, esto es muy seguro para evitar la colisión de nombres.
3. aproveche Object.defineProperty(), simplemente agregue una capa de protección adicional.

Como puedes ver, no es muy complicado.

Ahora viene el ventajas una vez que haya cuidado de los riesgos/desventajas:
1. encadenamiento de métodos, esto solo hace que el código sea más legible, conciso y que la codificación sea más agradable. A su vez te hace más feliz, y tu vida más fácil.
2. resuelve el problema de compatibilidad del navegador, está haciendo polyfill de todos modos.

P.d.:
No lo haga cuando trabaje con un equipo grande con seguridad.

 1
Author: alexcres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-05 02:37:11