比较Javascript中的函数

时间:2016-06-02 05:27:12

标签: javascript function

我有一个API,它将一个函数作为输入,然后在API内部,如果函数尚未添加到数组中,则意图将函数添加到数组中。

对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是什么。 API中的逻辑是什么来检测myArray中是否已存在该函数?

2 个答案:

答案 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);

答案 1 :(得分:0)

首先,比较函数是没有意义的,即使两个函数在字面上不同,它们在功能上可能是相同的。
对于您的问题,您可以比较它是否完全相同的对象,或者您可以使用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);
  };
}());