起源

几天前在实现一段业务逻辑的时候,写了一段代码,大概就是封装了一个报告类,然后根据传入的参数不同,获取不同的报告。报告类代码如下(具体业务逻辑已经去掉,?的代码纯粹为了说明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指向问题相关推荐

  1. 这是一个有趣的问题,Java 8 Lambda 表达式被编译成了什么?

    在了解了Java 8 Lambda的一些基本概念和应用后, 我们会有这样的一个问题: Lambda表达式被编译成了什么? 这是一个有趣的问题,涉及到JDK的具体的实现.本文将介绍OpenJDK对Lam ...

  2. 交互方式的系统总结:如何让App拥有一个有趣的“灵魂”?

    某一天,我突然在想:App的交互方式有哪些?不同的交互方式有什么区别?每一种交互方式主要的运用场景是什么?如何运用不同的交互方式创造出好玩又爽的体验? 然而,我并没有找到有关于上述问题的系统化的回答, ...

  3. 给小孩发布一个有趣的网站 在线动物园

    给小孩发布一个有趣的网站 在线动物园,可以实时看到动物园里的动物实时摄像头. 非常有意思,大热天也不用到动物园里看了. http://zoo.baidu.com/video.html

  4. 一个有趣的实验:用0.1f 替换 0,性能提升 7 倍!

    点击关注上方"视学算法",设为"置顶或星标",第一时间送达技术干货. 本文来源:http://cenalulu.github.io/linux/about-de ...

  5. 一个有趣的小例子,带你入门协程模块-asyncio

    上篇文章写了关于yield from的用法,简单的了解异步模式,[上次的内容链接]这次让我们通过一个有趣例子带大家了解asyncio基本使用. 目标效果图 在控制台中显示一个由ASCII字符" ...

  6. union一个有趣的应用

    今天在读<Linux高性能服务器编程>时看到一个有趣的东西.书中用了一个特别的方法去求字节序.我们知道字节序分为大端和小端,大端就是数据的高位字节存储在内存的低地址处,小段则反之.那么我们 ...

  7. 分享一个有趣的学习方法,欢迎一起探讨如何提高学习兴趣作者:1-2-3 来源:博客园 发布时间:2009-03-09 16:20 阅读:2820 次 原文链接 [收藏]

    分享一个有趣的学习方法,欢迎一起探讨如何提高学习兴趣 作者:1-2-3  来源:博客园  发布时间:2009-03-09 16:20  阅读:2820 次  原文链接   [收藏]   有些人似乎天生 ...

  8. 编写一个弹出式菜单的shell程序_分享一个有趣的shell脚本--实现抓阄程序

    概述 今天主要分享一个有趣的shell脚本,用来实现抓阄,平时就不用剪刀石头布了. 需求 使用shell编写一个抓阄的程序: 1.执行脚本后,输入英文名字全拼,产生随机数01-99之间的数字,数字越大 ...

  9. firebug的一个有趣现象

    firebug的一个有趣现象 var obj = {length:0,splice:function(){}}console.log(obj) 猜猜上面会打印出啥? 没错,打印出来的看起来是一个空数组 ...

最新文章

  1. onCompositionStart与compositionend
  2. 配置apache服务器的文件名,apache服务器配置文件名是
  3. Markdown 中的常用 LaTex 数学公式
  4. 电子老鼠闯迷宫pascal解题程序
  5. win7中PowerShell终端打开时自动进入python virtualenv的虚拟环境以及一键切换python版本
  6. .Net开发人员应该下载的十种必备工具(三)
  7. CentOS 7.8使用devtoolset-9使用高版本gcc version 9.3.1
  8. 使用IDEA逆向生成实体类时注意问题(Maven)
  9. (免费领)Java大厂面试题: 常见的异常类有哪些?
  10. [翻译]Chameleon介绍(6) : 动作控件
  11. pip和pip3 换源
  12. 超详细的四类数据库去重实现方案汇总(转载)
  13. 小米笔记本触摸板失灵问题
  14. 设计思维的定义与一些步骤
  15. powereshell判断目录如果存在pdf文件则打包文件发送到指定邮箱
  16. 计算机基本组成及功能
  17. 引用与引用作为函数的参数
  18. 基于JAVA网上汽车售票系统计算机毕业设计源码+数据库+lw文档+系统+部署
  19. 蓝桥杯 真题:明码 一题掌握3种码
  20. android 开发论坛资源URL

热门文章

  1. Perl中state()和localtime()函数
  2. html表单验证元素必填,AngularJS表单验证:向用户指示必填字段
  3. linux系统启动过程(一)
  4. 无线多操作系统启动之uInitrd阶段NFS挂载篇
  5. sublimeText3 工具
  6. [NOIP2006] 提高组 洛谷P1066 2^k进制数
  7. 新书《活用UML-需求分析高手》 序
  8. 如何重新安装TCP/IP协议
  9. 技校毕业是什么学历_技校毕业是什么学历
  10. vc++6.0获取磁盘基本信息_分享一个实用脚本--一键获取linux内存、cpu、磁盘IO等信息...