我有一个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中是否已存在该函数?
答案 0 :(得分:0)
addEventListener
和removeEventListener
出现同样的问题,其中回调必须相同(在===
意义上)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);
};
}());