学习对象字面量时,如何基于外部事件创建函数执行依赖?
解决方案
你的核心问题是没搞清楚事件监听的异步特性——addEventListener只是注册一个回调,不会阻塞代码等待事件触发,所以原来的init里直接调用functionOne和functionTwo会在事件触发前就执行,完全达不到依赖事件的目的。
下面提供两种常见场景的实现方式:
场景1:每次'appevent'触发都执行两个函数
把functionOne和functionTwo的调用直接放到事件回调里即可,同时注意保持this指向正确(用箭头函数或者bind):
var myObject = (function($) { var obj = { init: function() { this.eventCheck(); }, eventCheck: function() { // 用箭头函数保证this指向myObject实例 document.addEventListener('appevent', (e) => { console.log(e); // 事件触发时才执行两个函数 this.functionOne(); this.functionTwo(); }); }, functionOne: function() { console.log('执行functionOne'); // 你的业务逻辑 }, functionTwo: function() { console.log('执行functionTwo'); // 你的业务逻辑 }, }; return obj; })(jQuery); myObject.init();
场景2:仅第一次'appevent'触发时执行两个函数
如果只需要执行一次,可以手动移除监听,或者用once选项(现代浏览器原生支持):
var myObject = (function($) { var obj = { init: function() { this.eventCheck(); }, eventCheck: function() { const handleAppEvent = (e) => { console.log(e); this.functionOne(); this.functionTwo(); // 执行后移除监听,避免重复触发 document.removeEventListener('appevent', handleAppEvent); }; document.addEventListener('appevent', handleAppEvent); // 也可以用更简洁的once选项: // document.addEventListener('appevent', handleAppEvent, { once: true }); }, functionOne: function() { console.log('执行functionOne'); // 你的业务逻辑 }, functionTwo: function() { console.log('执行functionTwo'); // 你的业务逻辑 }, }; return obj; })(jQuery); myObject.init();
额外处理:事件可能提前触发的情况
如果'appevent'有可能在myObject.init()调用之前就已经触发,你可以用Promise来等待事件,同时加一个全局标志位记录触发状态:
var myObject = (function($) { var obj = { init: async function() { // 等待appevent触发(不管是已经触发还是未来触发) await this.waitForAppEvent(); this.functionOne(); this.functionTwo(); }, waitForAppEvent: function() { return new Promise(resolve => { // 先检查是否已经触发过 if (window.appEventTriggered) { resolve(); return; } const handleEvent = (e) => { console.log(e); window.appEventTriggered = true; document.removeEventListener('appevent', handleEvent); resolve(); }; document.addEventListener('appevent', handleEvent); }); }, functionOne: function() { console.log('执行functionOne'); }, functionTwo: function() { console.log('执行functionTwo'); }, }; return obj; })(jQuery); myObject.init();
内容的提问来源于stack exchange,提问作者mrmoon97
相关产品推荐
相关产品推荐

