有一定js开发经验的人一定会踩过this的坑。this这个问题也是老生常谈了。今天就来总结一下this到底有哪些坑,以及对应的解决思路。
先举个常见的坑:
var obj = {
a: 1,
b: function () {
console.log(this.a); // 1
setTimeout(function(){
console.log(this.a); // undefined
}, 1000)
}
}
第一个 console.log(this.a) 理解没问题,this.a 就是指向obj,因为谁是最后调用者的,就指向谁, 请记住:
this 永远指向最后调用它的那个对象
同样理解第二个,外面包裹了一个 setTimeout 方法,setTimeout是一个任务派发器,它实际上就是派发任务的,任务就是1秒钟后执行的这个方法,而setTimeout实际上就是window对象下的一个方法,1秒钟后执行的整个方法同样也是挂载在window对象下,而window对象根本没有定义window.a这个变量,所以是undefined;
怎么解决呢?
// 1;
var obj = {
a: 1,
b: function () {
console.log(this.a); // 1
var _this = this; // 拿到这个对象的上下文
setTimeout(function(){
console.log(_this .a); // 1
}, 1000)
}
}
第一种方法: 在setTimeout外面拿到当前对象的this赋值到一个变量_this, 然后在任务方法里面就可以正确拿到obj这个对象的引用了。
// 2 箭头函数,箭头函数是没有this的
var obj = {
a: 1,
b: function () {
console.log(this.a); // 1
setTimeout(() =>{
console.log(this .a); // 1
}, 1000)
}
}
第二种方法:箭头函数需要记着这句话:
箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined
// 3 , bind() 绑定this到另外一个对象
var obj = {
a: 1,
b: function () {
console.log(this.a); // 1
setTimeout(function(){
console.log(this.a); // 1
}.bind(this), 1000)
}
}
第三种方法:就是通过bind()这个方法主动改变这个任务方法的引用。