setInterval和setTImeout中的this指向问题

来源:互联网 发布:2016计算机二级vb真题 编辑:程序博客网 时间:2024/05/30 05:13

setInterval和setTimeout中传入函数时,函数中的this会指向window对象

var num = 0;function Obj (){    this.num = 1,    this.getNum = function(){        console.log(this.num);    },    this.getNumLater = function(){        setTimeout(function(){            console.log(this.num);        }, 1000)    }}var obj = new Obj; obj.getNum();//1  打印的为obj.num,值为1obj.getNumLater()//0  打印的为window.num,值为0

从上述例子中可以看到setTimeout中函数内的this是指向了window对象,这是由于setTimeout()调用的代码运行在与所在函数完全分离的执行环境上. 这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象。

但是在setTimeout中传入的不是函数时,this则指向当前对象,如下例:

var num = 0;function Obj (){    this.num = 1,    this.getNum = function(){        console.log(this.num);    },    this.getNumLater = function(){        setTimeout(console.log(this.num), 1000)    }}var obj = new Obj; obj.getNum();//1  打印的为obj.num,值为1obj.getNumLater()//1  打印的为obj.num,值为1

从以上两个例子可以看出,当在setTimeout中传入的参数为函数时,函数内部的this才会指向window对象。

当在setTimeout中传入了一个函数,若想要让this指向正确的值,可以使用以下两种比较常用的方法来使this指向正确的值:

1.将当前对象的this存为一个变量,定时器内的函数利用闭包来访问这个变量,如下:

var num = 0;function Obj (){    var that = this;    //将this存为一个变量,此时的this指向obj    this.num = 1,    this.getNum = function(){        console.log(this.num);    },    this.getNumLater = function(){        setTimeout(function(){            console.log(that.num);    //利用闭包访问that,that是一个指向obj的指针        }, 1000)    }}var obj = new Obj; obj.getNum();//1  打印的为obj.num,值为1obj.getNumLater()//1  打印的为obj.num,值为1

这种方法是将当前对象的引用放在一个变量里,定时器内部的函数来访问到这个变量,自然就可以得到当前的对象。

2.利用bind()方法

var num = 0;function Obj (){    this.num = 1,    this.getNum = function(){        console.log(this.num);    },    this.getNumLater = function(){        setTimeout(function(){            console.log(this.num);        }.bind(this), 1000)    //利用bind()将this绑定到这个函数上    }}var obj = new Obj; obj.getNum();//1  打印的为obj.num,值为1obj.getNumLater()//1  打印的为obj.num,值为1

bind()方法是在Function.prototype上的一个方法,当被绑定函数执行时,bind方法会创建一个新函数,并将第一个参数作为新函数运行时的this。在这个例子中,在调用setTimeout中的函数时,bind方法创建了一个新的函数,并将this传进新的函数,执行的结果也就是正确的了。
0 0