Pregunta

He añadido un archivo .js sencillo de mi página que tiene algunos bastante mundano-tarea común tipo de funciones añadidas a los prototipos Object y Array.

A través de ensayo y error, he descubierto que la adición de cualquier función para Object.prototype, sin importar su nombre o lo que hace provoca errores de Javascript en jQuery:

El culpable?

Object.prototype.foo = function() {
    /*do nothing and break jQuery*/
};

El error que estoy recibiendo la línea 1056 de jquery-1.3.2.js, en el attr: {} la función de declaración:

/*Object doesn't support this property or method*/
name = name.replace(/-([a-z])/ig, function(all, letter) {
            return letter.toUpperCase();
        });

Al parecer G.replace no está definido.

Si bien es evidente que hay algo que no estoy envolver mi cabeza alrededor de la creación de prototipos, estoy fracasando rotundamente a averiguar lo que es.

Para que quede claro, no estoy buscando una solución, tengo que maneja ... lo que estoy buscando es una respuesta a ¿Por qué? . ¿Por qué la adición de una función para Object.prototype romper este trozo de código?

¿Fue útil?

Solución

Nunca se debe extender Object.prototype. Se hace mucho más que romper jQuery; se rompe por completo la función de "objeto-como-tablas hash" de Javascript. No lo haga.

Puede pedir John Resig, y él le dirá el mismo .

Otros consejos

Si es simplemente un caso de echar a perder para ... en bucles, no puedes usar Object.defineProperty añadir su fn sin que sea numerable?

Así que:

Object.defineProperty(Object.prototype, "foo", { 
    value: function() {
        // do stuff
    },
    enumerable : false
});

Parece que funciona para mí. ¿Sería esto todavía se considera de mala educación?

Estoy de acuerdo, añadiendo algo a Object.prototype demandas precaución y debe ser evitado. Buscar otras soluciones tales como:

Adición a objeto y luego acceder a él con un call o apply, según sea necesario. Por ejemplo:

Object.foo = function () { return this.whatever()}

A continuación, llamar a eso en 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()

Para divertirse, puede añadir la siguiente (sí, sé que es un poco peligroso ...):

Function.using = Function.call; // syntactic sugar

Ahora se puede escribir Object.foo.using(Objname) y se lee como una frase o comentario.

Sin embargo, por regla general, se mantenga alejado de la alteración de cualquiera de los grandes prototipos.

Me golpeé la cabeza en torno a este problema como deseaba poner en práctica la orientación "real" objeto en todos mis objetos, como este:

interface Object
{
    GetType: () => string;
    ToString: () => string;
    GetHashcode: () => number;
    Equals: (obj: any) => boolean;
}

Desde Object.prototype rompe jQuery, que por defecto en la solución antes mencionada de hacer uso de defineProperty pero eso no tiene ningún argumento.

La buena noticia es que se puede cortar en defineProperty y, de hecho aceptar parámetros. Aquí está mi aplicació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.

Dudo que la adición de una función para Object.prototype rompe jQuery directamente. Sólo asegúrese de que cada bucle for..in usted tiene en todo su sitio está envuelto en un cheque hasOwnProperty, puesto que ya has añadir la función a nivel mundial y el resultado de la iteración en que no es previsible:

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
}}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top