どのようにしてbarとfooの等価性について肯定的なテストを取得できますか?
foo = function() {
a = 1;
};
bar = function() {
a = 1;
};
if (foo === bar) alert('baz');
if (foo == bar) alert('qux');
上記の条件はどちらも誤りです。
更新-要求どおり、関数の等価性をテストする必要がある理由
パブリッシュ/サブスクライブフレームワークを構築していて、トピックへのサブスクライブを解除するためにコールバックを渡す必要があります。
フィドルをご覧ください: http://jsfiddle.net/jamiefearon/hecMS/47/
toString
を呼び出した結果を比較することで、2つの関数の内容が正確にであるかどうかを確認できます
var foo = function() {
a = 1;
};
var bar = function() {
a = 1;
};
alert(foo.toString() == bar.toString());
ただし、異なる文字が1つしかない場合は失敗します。一方、2つの関数doが同じかどうかを確認することは、ほとんど不可能です。
問題は、関数の平等の概念が異なることです。
true
を提供します。 1つを割り当てるときは問題ですbar = foo
。 JavaScriptでは参照の等価性が使用されます。toSource
はW3C標準化されていないため、現在(2014年現在)Firefoxでのみ利用できます。だから、あなたが平等であると考えるものに注意してください。
イベントのNode.jsソースを見る場合
https://github.com/nodejs/node/blob/master/lib/events.js
コアチームが_===
_を使用して関数が等しいかどうかを比較していることがわかります。
関数に_===
_がどのように実装されているかはわかりませんが、2つの異なる関数が同じtoString()
結果を返す可能性があるため、toString()
ではないことを望みます。
2つの変数referがまったく同じ関数オブジェクトであるかどうかをテストし、関数を文字列に変換して、それらが本当に正確に同じですが、2つの関数がまったく同じことを実行するかどうかを判断しようとすると、少し難しくなるか、かなり難しくなります。
ミニファイアはかなりの量の静的分析を行うため、ミニファイアを介して関数のペアを実行すると興味深いでしょう。
この機能が必要な場合は、プログラムを少し再構成した方がよいかもしれません。このような何かがうまくいくかもしれません:
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
基本的に、それは一般的に不可能です。 JavaScriptで機能の等価性をテストする方法はありません。あなたが得ることができる最も近いものは、それらのコードを文字列として比較して等しいかどうかです。
シンプルなアプローチ:サブスクライブAPIを実装して、呼び出されるたびに一意のIDを返す場合、そのIDを使用してサブスクライブ解除APIを呼び出すのと同じくらい簡単です。内部的には単純なシナリオでは、単純な配列を使用してすべてのサブスクライバーを格納しますが、このアプローチでは格納する必要があります。 IDは、サブスクライブコールを1回実行するたびに増加できる単純なカウンターにすることができます。
{ID:サブスクライバーのコールバック関数}
したがって、すべてのサブスクライバーにパブリッシュする場合は、すべてのサブスクライバーを反復処理します。
高度なアプローチ:サブスクライブAPIで単純な関数名を受け入れる代わりに、onMessage関数(またはこのメソッドに付けたい名前)を持つクラスのオブジェクトを受け入れます。その後、同じオブジェクトのインスタンスを登録解除APIに渡すだけで、自分の登録を解除できます。サブスクライバーに通知する必要がある場合は、すべてのサブスクライバーのinstance.onMessage関数を呼び出すことができます。 2つのオブジェクト参照を比較するのは簡単です。