Frage

Ich habe eine einfache .js Datei auf meiner Seite hinzugefügt, die einige ziemlich banale Gemeinschaftsaufgabe Art von Funktionen zu den Object und Array Prototypen hinzugefügt hat.

Durch Versuch und Irrtum, ich habe, dass jede Funktion hinzugefügt herausgefunden Object.prototype, egal seinen Namen oder was es tut, führt Javascript-Fehler in jQuery:

Der Täter?

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

Der Fehler Ich erhalte Linie 1056 von jquery-1.3.2.js, in der attr: function {} Erklärung:

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

Offenbar G.replace ist nicht definiert.

Während es offensichtlich ist, dass es ich etwas einfach nicht mein Kopf Umwickeln mit Prototyping, ich kläglich scheitert, um herauszufinden, was es ist.

Um es klar, ich bin nicht für dieses Problem zu umgehen suchen, ich habe das behandelt ... was ich suche ist eine Antwort auf Warum? . Warum eine Funktion wirkt sich das Hinzufügen Object.prototype dieses Stück Code brechen?

War es hilfreich?

Lösung

Sie sollten nie Object.prototype verlängern. Es tut weit mehr als jQuery zu brechen; es bricht vollständig die „Objekt-as-Hash-Tabellen“ -Funktion von Javascript. Tun Sie es nicht.

Sie können John Resig fragen, und er wird dir die elbe sagen.

Andere Tipps

Wenn es einfach ein Fall von vermasselt für ... in Schleifen, können Sie nicht Object.defineProperty verwenden Ihre fn hinzuzufügen, ohne dass es enumerable?

So:

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

Es scheint, für mich zu arbeiten. Wäre dies noch schlechte Form in Betracht gezogen werden?

Ich bin damit einverstanden, was das Hinzufügen Anforderungen Vorsicht Object.prototype und sollte vermieden werden. Geben Sie für andere Lösungen, wie:

Hinzufügen es Objekt und dann mit einem call oder apply Zugriff, je nach Bedarf. Zum Beispiel:

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

Dann rufen Sie das auf ein Objekt durch:

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

Für Spaß, können Sie fügen Sie den folgenden (ja, ich weiß, es ist ein bisschen gefährlich ...):

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

Jetzt können Sie schreiben Object.foo.using(Objname) und es liest sich wie ein sentance.

Aber in der Regel bleiben weg eine der großen Prototypen zu verändern.

Ich schlug meinen Kopf, um dieses Problem wie ich wollte „echte“ Objektorientierung in alle meine Objekte implementieren, wie folgt aus:

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

Da Object.prototype bricht JQuery, ich auf die oben genannte Lösung vorbelegt Verwendung von DefineProperty zu machen, aber das nimmt keine Argumente.

Die gute Nachricht ist, dass Sie in DefineProperty hacken und tatsächlich Parameter akzeptieren. Hier ist meine Implementierung:

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

Das funktioniert und nicht mit JQuery kollidiert.

Ich bezweifle, das Hinzufügen einer Funktion zu Object.prototype bricht direkt jQuery. So stellen Sie sicher jede for..in-Schleife Sie haben auf Ihrer Website in einer hasOwnProperty Check gewickelt ist, da Sie die Funktion global haben addieren und das Ergebnis der Iteration über sie nicht vorhersehbar ist:

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
}}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top