我正在进行一项练习,现在正在创建一个自定义事件调度程序。
我得到了一堆测试用例,我在我的事件监听器对象上创建了一个名为hasCallbackFor(name,callback)的方法。从我可以收集的内容来看,hasCallbackFor函数应该在我创建的对象上取一个键的名称,而callback是一个位于该键的数组中的函数。它应该检查该功能是否存在。我完全迷失了如何做到这一点,感觉我已经尝试了一切。
这是hasCallbackFor函数的测试用例:
var shouldReturnFalseHasCallBackForIfMethodsNotAdded = function () {
testObj = {};
var scope = {
executeSuccess: true
}
var testFunction = function () {
if (this.executeSuccess) {
success1 = true;
}
}
EventDispatcher.mixin(testObj);
testObj.addEventListener('test', testFunction, scope);
testObj.dispatchEvent('test');
assert(testObj.hasCallbackFor("test", testFunction), 'should have callback registered for test event');
assert(!testObj.hasCallbackFor("test", function () {}), 'should have no callback');
console.log('shouldReturnFalseHasCallBackForIfMethodsNotAdded: success')
}
这是我的addEventListener函数:
/**
* @param {string} name
* @param {function} callback
* @param {Object} opt_scope
*/
addEventListener: function (name, callback, opt_scope) {
if(!EventDispatcher.myObject[name]) {
EventDispatcher.myObject[name] = [];
}
if(opt_scope) {
var bound = callback.bind(opt_scope);
EventDispatcher.myObject[name].push(bound);
} else {
EventDispatcher.myObject[name].push(callback);
}
},
这是我的dispatchEvent函数:
/**
* @param {string} name
*/
dispatchEvent: function (name) {
EventDispatcher.myObject[name].forEach(function(value) {
value();
});
},
对于我的hasCallbackFor函数,我试图使用
/**
* @param {string} name
* @param {function} callback
* @return {boolean}
*/
hasCallbackFor: function (name, callback) {
return EventDispatcher.myObject[name].includes(callback);
},
此功能未通过
的测试用例 assert(testObj.hasCallbackFor("test", testFunction), 'should have callback registered for test event');
一致,我已经完全没有想法了。我现在已经盯着这段代码大约3个小时了,并希望对此有任何见解。谢谢!
答案 0 :(得分:1)
在这种情况下,函数名称testFunction
是代码的地址
让我们考虑一个小例子:
var arr = [];
var foo = function(e){return true;};
arr.push(foo);
console.log(arr.includes(foo));//true
var bar = foo.bind('something');
arr.push(bar);
arr.includes(bar);//true
arr.includes(foo.bind('something'));//false .bind creates a new function every time
//The worst case:
arr.push(function(e){return true;});//anonymous function is lost forever
console.log(arr.includes(function(e){return true;}));//false
回到OP。问题出在这里:
var bound = callback.bind(opt_scope);//creates a new function with a new address
EventDispatcher.myObject[name].push(bound);
我提供两种解决方案:
从addEventListener
addEventListener: function (name, callback, opt_scope) {
if(!EventDispatcher.observable[name]) {
EventDispatcher.observable[name] = [];
}
if (opt_scope) {
var bound = callback.bind(opt_scope);
EventDispatcher.observable[name].push(bound);
return bound;
} else {
EventDispatcher.observable[name].push(callback);
return callback;
}
}
并在shouldReturnFalseHasCallBackForIfMethodsNotAdded
中调用此函数:
var foo = testObj.addEventListener('test', testFunction, scope);
// ^^^
testObj.dispatchEvent('test');
assert(testObj.hasCallbackFor("test", foo), 'should have callback registered for test event');
// ^^^
将功能绑定到shouldReturnFalseHasCallBackForIfMethodsNotAdded
,不要将scope
发送到addEventListener
//addEventListener is the same as in OP
var foo = testFunction.bind(scope);
testObj.addEventListener('test', foo, null);
testObj.dispatchEvent('test');
assert(testObj.hasCallbackFor("test", foo), 'should have callback registered for test event');
两者都有效。