Comment pourrais-je obtenir un test positif pour l'égalité de bar et foo?
foo = function() {
a = 1;
};
bar = function() {
a = 1;
};
if (foo === bar) alert('baz');
if (foo == bar) alert('qux');
Les deux conditions ci-dessus sont fausses.
Mise à jour - Comme demandé, la raison pour laquelle j'ai besoin de tester l'égalité de fonction
Je construis un framework Publish/Subscribe et je dois passer le rappel afin de me désabonner d'un sujet.
S'il vous plaît voir le violon: http://jsfiddle.net/jamiefearon/hecMS/47/
Vous pouvez vérifier si le contenu de deux fonctions est exactement le même en comparant le résultat de l'appel de toString
sur elles
var foo = function() {
a = 1;
};
var bar = function() {
a = 1;
};
alert(foo.toString() == bar.toString());
Cependant, cela échouera s’il n’ya qu’un caractère différent. Vérifier si deux fonctions do la même chose, en revanche, est quasiment impossible.
Le problème est qu’il existe différentes notions d’égalité des fonctions.
true
si les deux noms pointent vers la même adresse. C'est une question lorsque vous attribuez un bar = foo
. L'égalité de référence est utilisée en JavaScript.toSource
est actuellement (à partir de 2014) uniquement disponible dans Firefox, car il n'est pas standardisé par le W3C.Alors, prends soin de ce que tu penses que l'égalité est.
Si vous regardez la source des événements Node.js
https://github.com/nodejs/node/blob/master/lib/events.js
vous pouvez voir que l'équipe principale utilise ===
pour comparer les fonctions à égalité.
Je ne sais pas comment ===
est implémenté pour les fonctions, mais j'espère bien que ce n'est pas toString()
, car deux fonctions différentes pourraient avoir le même résultat toString()
.
Vous pouvez tester si deux variables référez au même objet fonction, et vous pouvez convertir des fonctions en chaînes et voir si elles sont vraiment identiques, mais en essayant de déterminer si deux fonctions font exactement même chose serait un peu plus difficile, ou peut-être beaucoup plus difficile.
Exécuter une paire de fonctions avec un minifier serait intéressant, car les minifiers effectuent une quantité considérable d’analyses statiques.
Il semble que si vous avez besoin de cette fonctionnalité, il serait peut-être préférable de restructurer un peu votre programme. Quelque chose comme ça pourrait marcher:
function baz(myInt) { return 3 + myInt; }
function asd(a) { return 3 + a; }
var foo = baz;
foo(1); //returns 4
var bar = baz;
bar(3); //returns 6
foo === bar; //true
bar = asd;
bar(3); //returns 6
foo === bar; //false
En gros, c'est impossible en général. Il n'y a aucun moyen de tester l'égalité fonctionnelle en javascript. Le plus proche que vous pouvez obtenir est de comparer leur code sous forme de chaîne pour l'égalité.
Approche simple: si vous implémentez votre API d'abonnement pour renvoyer un ID unique chaque fois qu'il est appelé, il vous suffira alors d'appeler une API de désabonnement avec cet ID. En interne, dans un scénario simple, vous utiliseriez un tableau simple pour stocker tous les abonnés, mais avec cette approche, vous devrez stocker. Un identifiant peut être un simple compteur que vous pouvez incrémenter avec chaque appel abonné.
{ID: fonction de rappel de l'abonné}
Donc, parcourez tous les abonnés lorsque vous souhaitez publier à tous les abonnés.
Approche avancée: au lieu d'accepter un nom de fonction simple dans l'API d'abonnement, acceptez un objet d'une classe qui devrait avoir une fonction onMessage (ou le nom que vous souhaitez donner à cette méthode). Ensuite, vous pouvez simplement passer la même instance d'objet à l'API de désabonnement pour vous désinscrire. Lorsque vous devez notifier un abonné, vous pouvez appeler la fonction instance.onMessage de tous les abonnés. Comparer deux objets de référence est facile.