Question

J'ai ajouté un simple fichier .js à ma page qui a une sorte de-tâche commune assez banale des fonctions ajoutées aux prototypes de Object et Array.

Par essais et erreurs, j'ai compris que l'ajout d'une fonction à Object.prototype, peu importe son nom ou ce qu'il fait provoque des erreurs javascript jQuery:

Le coupable?

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

L'erreur que je reçois la ligne 1056 de jquery-1.3.2.js, dans la attr: fonction {} déclaration:

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

Apparemment G.replace est indéfini.

Alors il est évident qu'il ya quelque chose que je ne suis pas envelopper ma tête avec le prototypage, j'échoue lamentablement à comprendre ce qu'il est.

Pour être clair, je ne suis pas à la recherche d'une solution, je ... qui a traité ce que je suis à la recherche est une réponse à Pourquoi? . Pourquoi ajouter une fonction à Object.prototype briser ce morceau de code?

Était-ce utile?

La solution

Vous ne devriez jamais étendre Object.prototype. Il fait beaucoup plus que briser jQuery; il se casse complètement la fonction de Javascript « objet-en-hashage ». Ne pas le faire.

Vous pouvez demander à John Resig, et il vous dira même chose .

Autres conseils

Si c'est tout simplement un cas de déconner pour ... en boucle, ne pouvez-vous utiliser Object.defineProperty pour ajouter votre fn sans en faire dénombrable?

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

Semble travailler pour moi. Serait-ce encore être considéré comme une mauvaise forme?

Je suis d'accord, ajouter quelque chose à Object.prototype exige une attention et devrait être évitée. Cherchez d'autres solutions telles que:

Ajout à objet, puis d'y accéder avec un call ou apply, au besoin. Par exemple:

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

Ensuite, appelez que sur un objet par:

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

Pour le plaisir, vous pouvez ajouter ce qui suit (oui, je sais que un peu dangereux ...):

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

Maintenant, vous pouvez écrire Object.foo.using(Objname) et il se lit comme un Sentance.

Mais en règle générale, rester à l'écart de modifier l'un des grands prototypes.

Je me suis cogné la tête autour de ce problème que je voulais mettre en œuvre l'orientation de l'objet « réel » dans tous mes objets, comme ceci:

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

Depuis casse Object.prototype JQuery, je DEFAILLANTE à la solution mentionnée ci-dessus à utiliser DefineProperty mais qui ne prend pas d'arguments.

Les bonnes nouvelles sont que vous pouvez pirater DefineProperty et accepter en fait des paramètres. Voici mon implémentation:

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

Cela fonctionne et ne pas en conflit avec JQuery.

Je doute l'ajout d'une fonction de casse Object.prototype jQuery directement. Assurez-vous que chaque boucle for..in vous avez tout au long de votre site est enveloppé dans un chèque de hasOwnProperty, puisque vous avez ajouter la fonction à l'échelle mondiale et le résultat de itérez peut être imprévisible:

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
}}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top