2017-10-18 170 views
0

我工作的锻炼,现在创建一个自定义事件调度创建hasCallbackFor功能。JAVASCRIPT:试图在自定义事件调度

我给出一堆的测试案例,和我被堵在我叫hasCallbackFor(名称,回调)事件侦听器对象创建的方法。据我所知,在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个小时了,并希望对此有所了解。谢谢!

回答

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

绑定在功能和不发送scopeaddEventListener

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

两个工作。

+0

谢谢你的帮助和详细的解释这么多!我知道它与指向不同事物的绑定函数有关,并且无法弄清楚如何解决它。再次谢谢你! – amacdonald