一个有趣的this指向问题
起源
几天前在实现一段业务逻辑的时候,写了一段代码,大概就是封装了一个报告类,然后根据传入的参数不同,获取不同的报告。报告类代码如下(具体业务逻辑已经去掉,?的代码纯粹为了说明this指向问题而写)
class ReportServer {getReport (reportType) {// 统一的获取报告方法return '获得'+ reportType +'报告'}getUserReport () {// 各自的业务处理。。。return this.getReport('用户')}getProductReport () {// 各自的业务处理。。。return this.getReport('产品')}getAreaReport () {// 各自的业务处理。。。return this.getReport('地域')} } 复制代码调用代码
const reportType = 'user' // 传入的参数 const reportServer = new ReportServer() const reportMap = {'user': reportServer.getUserReport,'product': reportServer.getProductReport,'area': reportServer.getAreaReport } reportMap[reportType]() 复制代码然后程序一运行,报了一个 TypeError: this.getReport is not a function 的错误。看到错误的第一秒,我的脑袋里闪过了我是谁?我在哪?我在干什么?下一秒:不可能!ReportServer这个类里面明明有getReport这个方法!
思考
言归正传,看到这个报错,第一反应就是this指向不对了,回忆了一下js中关于this的知识:
- 函数有所属对象,则指向所属对象
- 函数没有所属对象就指向全局对象
- 用new构造就指向新对象
- 通过 apply 或 call 或 bind 来改变 this 的所指。
没错,现在这个情况就是属于函数有所属对象,但是这个对象已经不在是reportServer,而是reportMap了,因为js中的this,是在函数真正执行的时候才会确认指向的。看看?的代码,更加强力的说明这一点
const reportMap = {'user': reportServer.getUserReport,'product': reportServer.getProductReport,'area': reportServer.getAreaReport,'test': 'test' } class ReportServer {//...getUserReport () {// 各自的业务处理。。。console.log(this)return this.getReport('用户')} }// 最后在执行时,这个this: { 'user': [Function: getUserReport],'product': [Function: getProductReport],'area': [Function: getAreaReport],'test': 'test' } 复制代码好吧,记得刚开始学习js的时候,还是有着重的去学习this这方面的知识,然而在实际开发中,还是会不经意的出错,幸好能第一时间反应过来Orz。
解决
好咯,既然是this指向问题,那么用call/apply指定正确的this:
reportMap[reportType].call(reportServer) // 输出:获得用户报告 复制代码或者使用?方法
const reportMap = {'user': 'getUserReport','product': 'getProductReport','area': 'getAreaReport' }reportServer[reportMap[reportType]]() // 输出:获得用户报告 复制代码再或者,改写为if-else的形式,当然我最开始用hash的写法,就是不想写if-else (⊙﹏⊙)
Thanks!
转载于:https://juejin.im/post/5caef2105188257111725bb6
总结
以上是生活随笔为你收集整理的一个有趣的this指向问题的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: java_11接口
- 下一篇: 云原生产业联盟成立 蚂蚁金服当选为理事单