一个有趣的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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值