2016-06-02 9 views
0

私は関数を入力として受け取り、その関数がまだ配列に追加されていない場合、APIの内部で、その関数を配列に追加します。Javascriptの関数を比較する

APIへの呼び出しの形式は次のとおりです。

myApiHandle.addIfUnique(function(){ 
    myResource.get(myObj); 
}); 

APIは以下のとおりです。

myApiHandle.addIfUnique(myFunc) { 
    if (myArray.indexOf(myFunc) === -1) { 
     return; 
    } 
// add to array 
} 

予想通りたびに新しい機能が渡されているので、今これは明らかに、動作しません。

私の質問です:myApiHandle.addIfUnique呼び出しに関数を渡す方法があります。これは、配列内の既存の関数をこの関数と比較することができます。現在は渡されていますか?比較では関数名とオブジェクトを比較し、両方が同じ場合は関数を配列に追加しないでください。可能であれば、addIfUnique呼び出しに別の引数を追加することは避けたい。もしそうなら

myApiCall.addIfUnique (someFunc) { 
} 

、someFuncです:つまり

は、可能下回っています。そして、関数がすでにmyArrayに存在するかどうかを検出するためのAPI内部のロジックは何ですか?

+2

indexOfで行っているような機能があるかどうかだけを確認できます。しかし、同じ関数を何度も作成しないようにaddIfUniqueを呼び出すコードを更新することができます。 –

+3

これは基本的にやってみると悪いことです。あなたの問題を別の方法で解決してください。 2つの異なる関数が実際に同じか異なっているかどうかを判断する方法はありません。確かに、もしそれらが全く同じコードを持っていれば、同じ結果を生み出しますが、それらが異なるコードを持っていれば、異なる結果を生むということではありません。私はあなたがそれらを比較したい場合は、毎回新たに作成されたローカル関数を渡すのを止めると言うでしょう。 – jfriend00

+0

私は同意します。あなたが解決しようとしている問題は何ですか? –

答えて

0

同じ問題は、それを除去するために、addEventListenerremoveEventListener、コールバックが同一でなければならない(===意味で)のためremoveEventListenerで起こります。あなたが見つけてきたように

は、明らかにあなたは、このようaddIfUniqueを呼び出す場合:

addIfUnique(function() { }) 

関数は毎回ユニークなオブジェクトになります渡されます。解決策は、一度関数を作成することです:

var fn = function() { }; 
addIfUnique(fn); 
addIfUnique(fn); 

に渡される関数はメソッド呼び出しであるので、私はそれをバインドする必要がある場合、関連する問題が発生します。

var x = { val: 42, method: function() { console.log(this.val); } }; 

私が渡したいです

addIfUnique(x.method.bind(x)); 
addIfUnique(x.method.bind(x)); 

また、x.method.bind(x)を呼び出すと別の機能が返されます。だから私は、バインドを事前する必要があります:すべての

var boundMethod = x.method.bind(x); 
addIfUnique(boundMethod); 
addIfUnique(boundMethod); 
0

まず、機能を比較すると、2つの関数は、文字通り異なっていても、意味がない、彼らは機能的に同じであってもよいです。
問題については、それがまったく同じオブジェクトかどうかを比較することができます。そうでない場合は、toString()関数とregExpを使用して文字通り比較することができます。

var addIfUnique = (function() { 
    var arr = []; 
    return function(func) { 
    if (~arr.indexOf(func)) return false; 
    var nameArr = []; 
    var funcName = func.name; 
    var funcRegExp = new RegExp('[^\{]+\{(.+)\}$', 'i'); 
    var funcStr = func.toString().match(funcRegExp); 
    funcStr = funcStr && funcStr[1]; 
    if (!funcStr) return false; 
    var strArr = arr.map(function(v){ 
     nameArr.push(v.name); 
     return v.toString().match(funcRegExp)[1]; 
    }); 
    if (~strArr.indexOf(funcStr) && ~nameArr.indexOf(funcName)) return false; 
    arr.push(func); 
    }; 
}());