this 关键字
this是Javascript语言的一个关键字。JavaScript 是一种脚本语言,因此被很多人认为是简单易学的。然而情况恰恰相反,JavaScript 支持函数式编程、闭包、基于原型的继承等高级功能,大家经常会困惑,this究竟指向谁,在这里先灌输一个概念别管this是谁,this 谁调指谁,没人调指window(global)。
谁调就指谁
this谁调指谁。例:
function a(){
this.b = 1
}
var c = new a();
console.info(c,c.b)//a:{b: 1} 1
复制代码
上面这行代码已经诠释了。此时的this指向对象c,因为我们答应的是c.b,c调用了b谁调指谁没毛病。
没人掉指global,换句话说还是谁调指谁
没人调用this会指向global,尝试查看下面两个代码片段
function a(){
this.b = 1;
}
a();
console.log(window.b) //1
复制代码
this.b = 1;
console.log(window.b) //1
复制代码
上面代码也诠释了this的指向问题。window调用b,所以this指向是window。
箭头函数
众所周知,箭头函数是es6的新语法,其实官网说的也很明白。它不能作为构造函数,例:
var a = ()=>{
this.b = 1
}
var c = new a() //报错:Uncaught TypeError: a is not a constructor
console.info(c.b)
复制代码
这就是为什么箭头函数不存在this的指向变更的本质。如果这里换成普通的function就是可以成立的。
总结
1.箭头函数的this绑定看的是this所在的函数定义在哪个对象下,绑定到哪个对象则this就指向哪个对象
2.如果有对象嵌套的情况,则this绑定到最近的一层对象上。
所以我们常说箭头函数的this问题,实际是比较箭头函数和普通function的方法。
setTimeout & setInterval
setTimeOut:“超时调用的代码都是在全局作用域中执行的,因此函数中this的值在非严格模式下指向window对象,在严格模式下是undefined”。在这里,我们只讨论非严格模式。
看看下面俩个代码片段:
箭头函数版本
function foo() {
this.b = 1
setTimeout(() => {
console.log('id:', this.b); //id: 1
}, 100);
}
var a = new foo()
console.log(a.b) // 1
复制代码
function版本
function foo() {
this.b = 1
setTimeout(function() {
console.log('id:', this.b); //id: undefined
}, 100);
}
var a = new foo()
console.log(a.b) //1
复制代码
那我们就想获取这个b用function版本怎么办呢?我们来尝试一下
改良版
function foo() {
var self = this;
self.b = 1
setTimeout(function() {
console.log('id:', self.b); //id: 1
}, 100);
}
var a = new foo()
复制代码
好的,达成目标~
结语
经过上面这番折腾,想必大家对这个this已经比较明白了。反正就是那句话,谁调指谁 ! 好了今天就到这里,去抽一根烟。