objeto - prototype javascript ejemplos
Objeto de creación de prototipos en Javascript rompe jQuery? (5)
He agregado un archivo .js
simple a mi página que tiene algunas funciones bastante triviales de tareas comunes agregadas a los prototipos de Object
y Array
.
A través del Object.prototype
prueba y error, he descubierto que agregar cualquier función a Object.prototype
, sin importar su nombre o lo que haga, causa errores de Javascript en jQuery:
¿El culpable?
Object.prototype.foo = function() {
/*do nothing and break jQuery*/
};
El error que estoy obteniendo es la línea 1056 de jquery-1.3.2.js
, en la declaración attr: function {}:
/*Object doesn''t support this property or method*/
name = name.replace(/-([a-z])/ig, function(all, letter) {
return letter.toUpperCase();
});
Aparentemente G.replace no está definido.
Si bien es obvio que hay algo que no me estoy volviendo loco con el prototipado, estoy fallando miserablemente para descubrir qué es.
Para ser claro, no estoy buscando una solución, lo he manejado ... lo que estoy buscando es una respuesta a ¿Por qué? . ¿Por qué agregar una función a Object.prototype
rompe este bit de código?
Dudo que se agregue una función a Object.prototype rompe jQuery directamente. Solo asegúrese de que cada bucle for..in que tenga en su sitio esté envuelto en una comprobación de hasOwnProperty, ya que ha agregado la función globalmente y el resultado de iterar sobre ella puede ser impredecible:
Object.prototype.foo = function() {};
var myObject = {m1: "one", m2: "two" };
for(var i in myObject) { if(myObject.hasOwnProperty(i)) {
// Do stuff... but not to Object.prototype.foo
}}
Estoy de acuerdo, agregar algo a Object.prototype
exige precaución y debe evitarse. Busque otras soluciones tales como:
Agregándolo a Object y luego accediéndolo con una call
o apply
, según sea necesario. Por ejemplo:
Object.foo = function () { return this.whatever()}
Luego llama eso a un objeto por:
Object.foo.call(Objname); // this invokes the function as though it were a
// method of Objname. That is, its like Objname.foo()
Por diversión, puede agregar lo siguiente (sí, sé que es un poco peligroso ...):
Function.using = Function.call; // syntactic sugar
Ahora puede escribir Object.foo.using(Objname)
y se lee como un sentance.
Pero, como regla general, evite alterar cualquiera de los grandes prototipos.
Me volví loco con este problema ya que deseaba implementar la orientación de objetos "real" en todos mis objetos, así:
interface Object
{
GetType: () => string;
ToString: () => string;
GetHashcode: () => number;
Equals: (obj: any) => boolean;
}
Como Object.prototype rompe JQuery, de manera predeterminada adopté la solución antes mencionada para hacer uso de defineProperty pero eso no toma ningún argumento.
La buena noticia es que puede hackear defineProperty y aceptar parámetros. Aquí está mi implementación:
Object.defineProperty(Object.prototype, "Equals",
{
value: function (obj: any)
{
return obj == null && this == null
? true
: obj != null && this == null
? false
: obj == null && this != null
? false
: this.GetHashcode() == obj.GetHashcode();
},
enumerable: false
});
Esto funciona y no entra en conflicto con JQuery.
Nunca debe extender Object.prototype
. Hace mucho más que romper jQuery; rompe por completo la función "objeto como hashtables" de Javascript. No lo hagas
Puedes preguntarle a John Resig, y él te dirá lo mismo .
Si se trata simplemente de desordenar ... en bucles, ¿no puede usar Object.defineProperty para agregar su fn sin que sea enumerable?
Asi que:
Object.defineProperty(Object.prototype, "foo", {
value: function() {
// do stuff
},
enumerable : false
});
Parece funcionar para mi. ¿Esto todavía se consideraría mala forma?