一道经典JS题(关于this)
项目中碰到的问题,以前也碰到过,没有重视,现记录如下。
复制代码<input type='button' value='click me' id='btn' /> <script> var num = 0; var obj = { num: 1, fn: function() { console.log(this.num); }, init: function() { setTimeout(this.fn, 0); document.getElementById('btn').addEventListener('click', this.fn, false); } }; obj.init(); </script>
输出啥?点击 button 后输出啥?
解决类似的问题其实很简单,只需要牢记下面一句话:
除了 DOM 的事件回调或者提供了执行上下文(call、apply、bind)的情况,函数正常被调用(不带new)时,里面的 this 指向的是全局作用域。
先看第一处,其实可以改写成这样:
复制代码setTimeout(function() {console.log(this.num); }, 0);
0ms后 函数正常被调用,里面的 this 指向全局作用域 window,所以输出即为 window.num,即为代码最开始定义的 num=0。
再看第二处,可以改写成这样:
复制代码document.getElementById('btn').addEventListener('click', function() { console.log(this.num); }, false);
click 后触发一个回调函数,属于 DOM事件回调,DOM 事件回调中的 this 指向该 DOM 元素。所以输出 this.num 即为 document.getElementById('btn').num,为 undefined。
如何能让 click 事件后输出 1?因为这种需求在生产中很常见,绑定各种事件,回调已经定义的对象方法。很明显,归根结底需要改变函数中 this 指向。
方法一:
再加一层匿名函数,使得 fn 被 obj 调用:
复制代码var that = this;
document.getElementById('btn').addEventListener('click', function() { that.fn(); }, false);
方法二:
用 bind 改变 this 指向:
复制代码// 兼容IE
Function.prototype.bind = Function.prototype.bind || function(context) { var that = this; return function() { return that.apply(context, arguments); } } document.getElementById('btn').addEventListener('click', this.fn.bind(this), false);
转载于:https://www.cnblogs.com/zhengxingpeng/p/6678747.html
一道经典JS题(关于this)相关推荐
- 一道经典极限题的分析与求解
一道经典极限题的分析与求解 题目 limx→∞ex(1+1x)x2\lim_{x\to \infty}\frac{\mathrm{e}^x}{(1+\frac1x)^{x^2}} x→∞lim(1 ...
- 微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日
微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日 分类: 天下杂侃 2008-08-07 23:37 17495人阅读 评论(21) 收藏 举报 题目是这样的: 小明和小强 ...
- 微软的一道经典逻辑推理题 小明和小强都是张老师的学生,张老师的生日是M月N日
微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日 分类: 天下杂侃 2008-08-07 23:37 17495人阅读 评论(21)收藏 举报 题目是这样的: 小明和小强都 ...
- 微软的一道经典逻辑推理题
题目是这样的: 小明和小强都是张老师的学生,张老师的生日是M月N日,2人都不知道张老师的生日是下列10组中的一天,张老师把M值告诉了小明,把N值告诉了小强,张老师问他们知道他的生日是那一天吗? 3月4 ...
- 微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日...
题目是这样的: 小明和小强都是张老师的学生,张老师的生日是M月N日,2人都不知道张老师的生日是下列10组中的一天,张老师把M值告诉了小明,把N值告诉了小强,张老师问他们知道他的生日是那一天吗? 3月4 ...
- c++ 结构体构造函数使用总结 附一道经典模拟题
要点 :建立结构体数组时,如果只写了带参数的构造函数将会出现数组无法初始化的错误 下面是一个比较安全的带构造的结构体示例 struct node {int data;string str;char c ...
- java并发编程--一道经典多线程题的2种解法
问题的描述 启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15. 接着再由线程1打印16,17,18, ...
- 一道经典推理题(常玩能提高逻辑思维能力哦)
有甲乙丙三人,丙叫甲和乙各伸出一只手,给甲乙二人手心中各写了一个数字,并告诉他们: "你们两个手心中的数字,都是比一大且比四十小的数字:我的两手的手心也各有一个数字,我这两个数字之和,就是甲 ...
- LeetCode刷题——链表OJ(历时三天,万字博客,十一道经典题,带你手撕链表)
知之愈明,则行之愈笃:行之愈笃,则知之益明. 学完链表,我们不得刷刷题增进对链表的认识?今天博主选取十一道经典链表题,从刷题者的角度剖析重点和易错点,讲解最简单的方法,文章内附题目和题目链接,重点内容 ...
- 关于欧拉工程的一道递推题
今天来讲的是在欧拉工程上的一道递推题,题目描述如下链接. 题目:https://projecteuler.net/problem=492 当然,这道题在51Nod上有一个比较通用的版本,链接如下 题目 ...
最新文章
- GitHUb 代码提交遇到的问题以及解决办法
- tensorflow2.2.0安装_Zabbix5.0安装部署
- java 开源控件_一些好用的开源控件
- MySQL 开启远程访问权限 | 宝塔系统
- A4Desk 网站破解
- TCP/IP完整的基础介绍
- LeetCode 2131. 连接两字母单词得到的最长回文串
- 惠普台式计算机系列,惠普发布设计笔记本、设计台式电脑等Z系列产品
- 强烈推荐:给去美国的新生说几句(转载),超实用
- Android开发笔记(六十五)多样的菜单
- 如何强制.NET应用程序以管理员身份运行?
- 渲染进行调用_UE渲染师Dyomin:做次世代手游,可以用好这项技能
- Python Lex Yacc手册
- account.php,account.php
- 施努卡:3d视觉检测方案 3d视觉检测应用行业
- Readiris Pro 17 for Mac(光学识别OCR软件)
- 使用阿里云的身份证实名认证接口
- 电脑网络异常故障解决办法
- 数字图像处理大作业实验报告
- 必读论文 | 卷积神经网络百篇经典论文推荐
热门文章
- 设置IDEA修改html、jsp后立即生效,不用重启项目
- 使用freemarker模板生成html文件(一)
- 【渝粤教育】国家开放大学2018年春季 7385-21T公共关系学(本) 参考试题
- 【渝粤教育】 广东开放大学 10331k2_行政管理学_21秋考试
- 【Python实例第27讲】增量PCA
- 【Python实例第2讲】特征提取集成方法
- 线性规划 (一) 线性规划的基本形式及各种概念
- 线段树(SegmentTree)学习笔记
- mac系统下为emacs设置中文字体,解决乱码问题
- Shell脚本中替换字符串等操作