JAVASCRIPT:试图在自定义事件调度程序上创建hasCallbackFor函数



我现在正在做一个练习,创建一个自定义事件调度器。

我收到了一堆测试用例,我一直在为我的事件侦听器对象创建一个名为hasCallbackFor(name,callback)的方法。据我所知,hasCallbackFor函数应该取我正在创建的对象上的一个键的名称,回调是位于该键的数组中的一个函数。它应该检查该函数是否存在。我完全不知道该怎么做,感觉自己什么都试过了。

这是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个小时了,如果有任何关于这方面的见解,我将不胜感激。非常感谢。

在这种情况下,函数名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中的函数,不向addEventListener发送scope

//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');

两者都有效。

相关内容

  • 没有找到相关文章

最新更新