一个有趣的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 8 Lambda 表达式被编译成了什么?
在了解了Java 8 Lambda的一些基本概念和应用后, 我们会有这样的一个问题: Lambda表达式被编译成了什么? 这是一个有趣的问题,涉及到JDK的具体的实现.本文将介绍OpenJDK对Lam ...
- 交互方式的系统总结:如何让App拥有一个有趣的“灵魂”?
某一天,我突然在想:App的交互方式有哪些?不同的交互方式有什么区别?每一种交互方式主要的运用场景是什么?如何运用不同的交互方式创造出好玩又爽的体验? 然而,我并没有找到有关于上述问题的系统化的回答, ...
- 给小孩发布一个有趣的网站 在线动物园
给小孩发布一个有趣的网站 在线动物园,可以实时看到动物园里的动物实时摄像头. 非常有意思,大热天也不用到动物园里看了. http://zoo.baidu.com/video.html
- 一个有趣的实验:用0.1f 替换 0,性能提升 7 倍!
点击关注上方"视学算法",设为"置顶或星标",第一时间送达技术干货. 本文来源:http://cenalulu.github.io/linux/about-de ...
- 一个有趣的小例子,带你入门协程模块-asyncio
上篇文章写了关于yield from的用法,简单的了解异步模式,[上次的内容链接]这次让我们通过一个有趣例子带大家了解asyncio基本使用. 目标效果图 在控制台中显示一个由ASCII字符" ...
- union一个有趣的应用
今天在读<Linux高性能服务器编程>时看到一个有趣的东西.书中用了一个特别的方法去求字节序.我们知道字节序分为大端和小端,大端就是数据的高位字节存储在内存的低地址处,小段则反之.那么我们 ...
- 分享一个有趣的学习方法,欢迎一起探讨如何提高学习兴趣作者:1-2-3 来源:博客园 发布时间:2009-03-09 16:20 阅读:2820 次 原文链接 [收藏]
分享一个有趣的学习方法,欢迎一起探讨如何提高学习兴趣 作者:1-2-3 来源:博客园 发布时间:2009-03-09 16:20 阅读:2820 次 原文链接 [收藏] 有些人似乎天生 ...
- 编写一个弹出式菜单的shell程序_分享一个有趣的shell脚本--实现抓阄程序
概述 今天主要分享一个有趣的shell脚本,用来实现抓阄,平时就不用剪刀石头布了. 需求 使用shell编写一个抓阄的程序: 1.执行脚本后,输入英文名字全拼,产生随机数01-99之间的数字,数字越大 ...
- firebug的一个有趣现象
firebug的一个有趣现象 var obj = {length:0,splice:function(){}}console.log(obj) 猜猜上面会打印出啥? 没错,打印出来的看起来是一个空数组 ...
最新文章
- onCompositionStart与compositionend
- 配置apache服务器的文件名,apache服务器配置文件名是
- Markdown 中的常用 LaTex 数学公式
- 电子老鼠闯迷宫pascal解题程序
- win7中PowerShell终端打开时自动进入python virtualenv的虚拟环境以及一键切换python版本
- .Net开发人员应该下载的十种必备工具(三)
- CentOS 7.8使用devtoolset-9使用高版本gcc version 9.3.1
- 使用IDEA逆向生成实体类时注意问题(Maven)
- (免费领)Java大厂面试题: 常见的异常类有哪些?
- [翻译]Chameleon介绍(6) : 动作控件
- pip和pip3 换源
- 超详细的四类数据库去重实现方案汇总(转载)
- 小米笔记本触摸板失灵问题
- 设计思维的定义与一些步骤
- powereshell判断目录如果存在pdf文件则打包文件发送到指定邮箱
- 计算机基本组成及功能
- 引用与引用作为函数的参数
- 基于JAVA网上汽车售票系统计算机毕业设计源码+数据库+lw文档+系统+部署
- 蓝桥杯 真题:明码 一题掌握3种码
- android 开发论坛资源URL
热门文章
- Perl中state()和localtime()函数
- html表单验证元素必填,AngularJS表单验证:向用户指示必填字段
- linux系统启动过程(一)
- 无线多操作系统启动之uInitrd阶段NFS挂载篇
- sublimeText3 工具
- [NOIP2006] 提高组 洛谷P1066 2^k进制数
- 新书《活用UML-需求分析高手》 序
- 如何重新安装TCP/IP协议
- 技校毕业是什么学历_技校毕业是什么学历
- vc++6.0获取磁盘基本信息_分享一个实用脚本--一键获取linux内存、cpu、磁盘IO等信息...