调用createAsyncThunk函数时自定义库中this未定义问题排查
对象箭头函数this指向错误的原因与解决方法
问题根源:箭头函数的this绑定逻辑
你踩了箭头函数的典型误区:箭头函数没有自己的this,它的this是继承自定义时的外层词法作用域。
在你的log.js里,log作为箭头函数定义在模块顶级作用域下的logger对象中,而ES模块的顶级作用域里this本身就是undefined——所以不管你在createAsyncThunk还是任何地方调用logger.log(),这个箭头函数里的this永远都是undefined,自然取不到this.enabled。
你原本以为箭头函数能解决对象方法的this问题,其实搞反了:普通函数作为对象方法时,this才会指向调用它的对象(比如logger.log()调用时,this就是logger),箭头函数反而会切断和对象的this绑定。
不修改直接引用logger的解决方案
最直接且符合JS规范的改法是把箭头函数改成普通函数:
// log.js 修改后的代码 const logger = { enabled: false, // 换成普通函数,不再用箭头函数 log(label, value) { let isEnabled = false; console.log("BEFORE this"); try { isEnabled = this.enabled; // 此时this指向logger对象 console.log("AFTER this"); } catch(err) { console.log("ERR calling this ", err); } if (!isEnabled) { return; } console.log(label, value); } }; export default logger;
这样不管你在createAsyncThunk的异步函数里还是其他任何地方调用logger.log(),this都会正确指向logger对象,就能正常读取enabled属性。
关于在createAsyncThunk中使用this的可行性
当然可以用,但前提是要保证this的指向正确。只要你用普通函数作为对象方法,并且通过logger.log()的方式调用(而不是解构后单独调用log()),this就会稳定指向logger,和调用环境(包括createAsyncThunk的异步函数)无关。
额外说明:非要用箭头函数的替代方案(不推荐)
如果坚持要用箭头函数,只能通过闭包引用对象本身,本质和直接写logger.enabled差别不大:
// 不推荐的写法,仅作示例 const logger = (() => { const innerLogger = { enabled: false, log: (label, value) => { let isEnabled = false; console.log("BEFORE this"); try { isEnabled = innerLogger.enabled; // 用闭包引用内部对象 console.log("AFTER this"); } catch(err) { console.log("ERR calling this ", err); } if (!isEnabled) { return; } console.log(label, value); } }; return innerLogger; })(); export default logger;
这种写法没有必要,反而违背了对象方法的常规设计逻辑,更推荐用普通函数的方案。
内容的提问来源于stack exchange,提问作者Sammybar
相关产品推荐
相关产品推荐

