使用js中的定时器(setInterval,setTimeout),很容易会遇到this指向的问题。

直接上例子:

 1 var name = 'my name is window';
2 var obj = {
3 name: 'my name is obj',
4 fn: function () {
5 var timer = null;
6 clearInterval(timer);
7 timer = setInterval(function () {
8 console.log(this.name);  //my name is window
9 }, 1000)
10 }
11 }

在这里,从this.name可以看出this的指向是window。

如果没有特殊指向,setInterval和setTimeout的回调函数中this的指向都是window。这是因为JS的定时器方法是定义在window下的。但是平时很多场景下,都需要修改this的指向。这里总结了几种:

1、最常用的方法:在外部函数中将this存为一个变量,回调函数中使用该变量,而不是直接使用this。

 1 var name = 'my name is window';
2 var obj = {
3 name: 'my name is obj',
4 fn: function () {
5 var that = this;
6 var timer = null;
7 clearInterval(timer);
8 timer = setInterval(function () {
9 console.log(that.name); //my name is obj
10 }, 1000)
11 }
12 }

在fn中加了var that = this; 回调函数中使用that代替this即可。这种方法最常见,使用也最广泛。

2、使用bind()方法(bind()为ES5的标准,低版本IE下有兼容问题,可以引入es5-shim.js解决)

bind()的作用类似call和apply,都是修改this指向。但是call和apply是修改this指向后函数会立即执行,而bind则是返回一个新的函数,它会创建一个与原来函数主体相同的新函数,新函数中的this指向传入的对象。

 1 var name = 'my name is window';
2 var obj = {
3 name: 'my name is obj',
4 fn: function () {
5 var timer = null;
6 clearInterval(timer);
7 timer = setInterval(function () {
8 console.log(this.name); //my name is obj
9 }.bind(this), 1000)
10 }
11 }

在这里为什么不能用call和apply,是因为call和apply不是返回函数,而是立即执行函数,那么,就失去了定时器的作用。

3、使用es6的箭头函数:箭头函数的最大作用就是this指向。

 1 var name = 'my name is window';
2 var obj = {
3 name: 'my name is obj',
4 fn: function () {
5 var timer = null;
6 clearInterval(timer);
7 timer = setInterval(() => {
8 console.log(this.name); //my name is obj
9 }, 1000)
10 }
11 }

箭头函数没有自己的this,它的this继承自外部函数的作用域。所以,在该例中,定时器回调函数中的this,是继承了fn的this。当然箭头函数也有兼容问题,要是兼容低版本ie,需要使用babel编译,并且引入es5-shim.js才可以。

转载自https://www.cnblogs.com/443855539-wind/p/6480673.html

Javascript回调函数中的this指向问题的更多相关文章

  1. JS回调函数中的this指向(详细)

    首先先说下正常的this指向问题 什么是this:自动引用正在调用当前方法的.前的对象. this指向的三种情况 1. obj.fun()     fun中的this->obj,自动指向.前的对 ...

  2. JavaScript 回调函数中的 return false 问题

    今天一个同事问了我一个问题,就是在 Ajax 方法中,请求成功后(success)的回调函数中根据响应的值来判断程序是否继续执行,他不解的是在回调函数中已经 return false 了,但是 Aja ...

  3. 理解 JavaScript 回调函数并使用

    JavaScript中,函数是一等(first-class)对象:也就是说,函数是 Object 类型并且可以像其他一等对象(String,Array,Number等)一样使用.它们可以"保 ...

  4. 理解 JS 回调函数中的 this

    任何变量或对象都有其赖以生存的上下文.如果简单地将对象理解为一段代码,那么对象处在不同的上下文,这段代码也会执行出不同的结果. 例如,我们定义一个函数 getUrl 和一个对象 pseudoWindo ...

  5. 理解javascript 回调函数

    ##回调函数定义 百度百科:回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数.回调函数不 ...

  6. javascript回调函数,闭包作用域,call,apply函数解决this的作用域问题

    在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...

  7. 使用匿名函数在回调函数中正确访问JS循环变量

    有时候, 需要以不同的参数调用某个URL,并且在回调函数中仍然可以访问正在使用的参数, 这时候, 需要使用闭包保存当前参数, 否则, 当回调函数执行时, 之前的参数很可能早已被修改为最后一个参数了. ...

  8. 【JavaScript】JavaScript回调函数

    什么是Javascript 回调函数? 函数和其他数据一样可以被赋值,删除,拷贝等,所以也可以把函数作为参数传入到另一个函数中. 这个函数就是所谓的回调函数   举例: //不带参数的case fun ...

  9. javascript回调函数笔记

    来源于:https://github.com/useaname/blog-study 在Javascript中,函数是第一类对象.意味函数可以像对象一样按照第一类被管理使用.回调函数是从一个叫函数式编 ...

随机推荐

  1. Zabbix配置网络流量监控报警

    一.SNMP简单概述 1.什么是Snmp SNMP是英文"Simple Network Management Protocol"的缩写,中文意思是"简单网络管理协议&qu ...

  2. maven中target不能访问

    原因是maven  clean的时候已经把target文件夹删除  但是文件夹还存在页面中  所以我们看得到但是不能打开.正常操作是获得管理员权限删除后再重新clean,但是我电脑有360,直接360 ...

  3. mysql在Windows下使用mysqldump命令手动备份数据库和自动备份数据库

    手动备份: cmd控制台: 先进入mysql所在的bin目录下,如:cd C:\Program Files\MySQL\MySQL Server 5.5\bin mysqldump -u root - ...

  4. Navicat Premium 简体中文版 12.0.16 以上版本国外官网下载地址(非国内)

    国内Navicat网址是:http://www.navicat.com.cn 国外Navicat网址是:http://www.navicat.com 国外的更新比国内的快,而且同一个版本,国内和国外下 ...

  5. Python数据分析Pandas库之熊猫(10分钟二)

    pandas 10分钟教程(二) 重点发法 分组 groupby('列名') groupby(['列名1','列名2',.........]) 分组的步骤 (Splitting) 按照一些规则将数据分 ...

  6. CentOS与Win7远程桌面互通

    在CentOS上装上Rdesktop即可连接Windows,如下命令,第一次执行时报错,提示CredSSP required by server. [root@localhost ~]# rdeskt ...

  7. bash 和sed 和gawk

    bash内建命令 命令描述 : 扩展参数列表,执行重定向操作 . 读取并执行指定文件中的命令(在当前shell环境中) alias 为指定命令定义一个别名 bg 将作业以后台模式运行 bind 将键盘 ...

  8. \r \n \t \n\t

    [root@localhost advanced_shell_script]# cat test15.sh #!/bin/bash #!/bin/bash # echo -e# 默认情况下,echo命 ...

  9. 迭代(遍历)时候不可以使用集合的remove和add方法,但可使用Java迭代器的remove和add方法

    不要在 foreach 循环里进行元素的 remove/add 操作.remove 元素请使用 Iterator 方式. 反例: public class ForeachTest { private ...

  10. python 包 笔记

    绝对导入和相对导入 我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式: 绝对导入:以glance作为起始 相对导入: ...