项目中碰到的问题,以前也碰到过,没有重视,现记录如下。

复制代码<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)相关推荐

  1. 一道经典极限题的分析与求解

    一道经典极限题的分析与求解 题目 lim⁡x→∞ex(1+1x)x2\lim_{x\to \infty}\frac{\mathrm{e}^x}{(1+\frac1x)^{x^2}} x→∞lim​(1 ...

  2. 微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日

    微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日 分类: 天下杂侃 2008-08-07 23:37 17495人阅读 评论(21) 收藏 举报 题目是这样的: 小明和小强 ...

  3. 微软的一道经典逻辑推理题 小明和小强都是张老师的学生,张老师的生日是M月N日

    微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日 分类: 天下杂侃 2008-08-07 23:37 17495人阅读 评论(21)收藏 举报 题目是这样的: 小明和小强都 ...

  4. 微软的一道经典逻辑推理题

    题目是这样的: 小明和小强都是张老师的学生,张老师的生日是M月N日,2人都不知道张老师的生日是下列10组中的一天,张老师把M值告诉了小明,把N值告诉了小强,张老师问他们知道他的生日是那一天吗? 3月4 ...

  5. 微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日...

    题目是这样的: 小明和小强都是张老师的学生,张老师的生日是M月N日,2人都不知道张老师的生日是下列10组中的一天,张老师把M值告诉了小明,把N值告诉了小强,张老师问他们知道他的生日是那一天吗? 3月4 ...

  6. c++ 结构体构造函数使用总结 附一道经典模拟题

    要点 :建立结构体数组时,如果只写了带参数的构造函数将会出现数组无法初始化的错误 下面是一个比较安全的带构造的结构体示例 struct node {int data;string str;char c ...

  7. 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, ...

  8. 一道经典推理题(常玩能提高逻辑思维能力哦)

    有甲乙丙三人,丙叫甲和乙各伸出一只手,给甲乙二人手心中各写了一个数字,并告诉他们: "你们两个手心中的数字,都是比一大且比四十小的数字:我的两手的手心也各有一个数字,我这两个数字之和,就是甲 ...

  9. LeetCode刷题——链表OJ(历时三天,万字博客,十一道经典题,带你手撕链表)

    知之愈明,则行之愈笃:行之愈笃,则知之益明. 学完链表,我们不得刷刷题增进对链表的认识?今天博主选取十一道经典链表题,从刷题者的角度剖析重点和易错点,讲解最简单的方法,文章内附题目和题目链接,重点内容 ...

  10. 关于欧拉工程的一道递推题

    今天来讲的是在欧拉工程上的一道递推题,题目描述如下链接. 题目:https://projecteuler.net/problem=492 当然,这道题在51Nod上有一个比较通用的版本,链接如下 题目 ...

最新文章

  1. GitHUb 代码提交遇到的问题以及解决办法
  2. tensorflow2.2.0安装_Zabbix5.0安装部署
  3. java 开源控件_一些好用的开源控件
  4. MySQL 开启远程访问权限 | 宝塔系统
  5. A4Desk 网站破解
  6. TCP/IP完整的基础介绍
  7. LeetCode 2131. 连接两字母单词得到的最长回文串
  8. 惠普台式计算机系列,惠普发布设计笔记本、设计台式电脑等Z系列产品
  9. 强烈推荐:给去美国的新生说几句(转载),超实用
  10. Android开发笔记(六十五)多样的菜单
  11. 如何强制.NET应用程序以管理员身份运行?
  12. 渲染进行调用_UE渲染师Dyomin:做次世代手游,可以用好这项技能
  13. Python Lex Yacc手册
  14. account.php,account.php
  15. 施努卡:3d视觉检测方案 3d视觉检测应用行业
  16. Readiris Pro 17 for Mac(光学识别OCR软件)
  17. 使用阿里云的身份证实名认证接口
  18. 电脑网络异常故障解决办法
  19. 数字图像处理大作业实验报告
  20. 必读论文 | 卷积神经网络百篇经典论文推荐

热门文章

  1. 设置IDEA修改html、jsp后立即生效,不用重启项目
  2. 使用freemarker模板生成html文件(一)
  3. 【渝粤教育】国家开放大学2018年春季 7385-21T公共关系学(本) 参考试题
  4. 【渝粤教育】 广东开放大学 10331k2_行政管理学_21秋考试
  5. 【Python实例第27讲】增量PCA
  6. 【Python实例第2讲】特征提取集成方法
  7. 线性规划 (一) 线性规划的基本形式及各种概念
  8. 线段树(SegmentTree)学习笔记
  9. mac系统下为emacs设置中文字体,解决乱码问题
  10. Shell脚本中替换字符串等操作