Domanda

Ho aggiunto un semplice file .js alla mia pagina che ha alcuni piuttosto banale comune compito sorta di funzioni aggiunte alle Object e Array prototipi.

Attraverso tentativi ed errori, ho capito che l'aggiunta di una funzione per Object.prototype, non importa il suo nome o quello che fa provoca errori Javascript in jQuery:

Il colpevole?

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

L'errore che sto ottenendo la linea 1056 di jquery-1.3.2.js, nel attr: funzione di {} dichiarazione:

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

A quanto pare G.replace non è definito.

Mentre è evidente che c'è qualcosa che non sto solo confezionamento mia testa intorno alla prototipazione, sto fallendo miseramente per capire di cosa si tratta.

Per essere chiari, non sto cercando una soluzione, ho che ha gestito ... quello che sto cercando una risposta a Perché? . Perché l'aggiunta di una funzione per Object.prototype rompere questo pezzo di codice?

È stato utile?

Soluzione

Non si dovrebbe mai estendersi Object.prototype. Lo fa molto di più che rompere jQuery; si rompe completamente la funzione "oggetto-as-hashtables" di Javascript. Non farlo.

Si può chiedere John Resig, e ti dirà la stessa cosa .

Altri suggerimenti

Se è semplicemente un caso di rovinare per ... in loop, non è possibile utilizzare Object.defineProperty aggiungere la fn senza farne enumerabile?

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

sembra funzionare per me. Sarebbe questo ancora essere considerato di cattivo gusto?

Sono d'accordo, l'aggiunta di qualcosa di Object.prototype esigenze cautela e dovrebbe essere evitato. Cercare altre soluzioni come ad esempio:

aggiungendolo oggetto e poi accedervi con un call o apply, come necessario. Ad esempio:

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

Quindi chiamare che su un oggetto da:

Object.foo.call(Objname);  // this invokes the function as though it were a
                           // method of Objname.  That is, its like Objname.foo()

Per il divertimento, è possibile aggiungere la seguente (sì, So che è un po 'pericoloso ...):

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

Ora è possibile scrivere Object.foo.using(Objname) e si legge come un sentance.

Ma, come regola, stare lontano da alterare qualsiasi dei grandi prototipi.

Ho sbattuto la testa intorno a questo problema come ho voluto attuare "vero" orientamento oggetto in tutti i miei oggetti, in questo modo:

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

Dal Object.prototype rompe JQuery, ho in default alla soluzione di cui sopra di fare uso di defineProperty ma che non tiene alcun argomento.

La buona notizia è che si può incidere in defineProperty e in realtà accettare parametri. Qui è la mia realizzazione:

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
    });

Questo funziona e non si scontra con JQuery.

Dubito l'aggiunta di una funzione per Object.prototype rompe direttamente jQuery. Basta fare in modo ogni ciclo for..in avete tutto il sito è avvolto in un controllo hasOwnProperty, dal momento che hai aggiungere la funzione a livello globale e il risultato di iterando su di esso può essere imprevedibile:

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
}}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top