javaScript中的this,无处不在,但他的指向,又真的没有那么简单,所以在这里记录下,方便以后模糊了查看。
首要的记忆点:this在标准函数和箭头函数中有不同的行为。
标准函数中,this引用的是把函数当成方法调用的上下文对象,在网页全局下调用函数时,this指向就是window,如果在对象中调用函数,this指向的就是该对象,用下面的例子来解释下:
window.a = '这是window的a'
function printA() {
console.log(this.a)
}
let A = {
a: '这是A对象的a'
}
A.printA = printA
printA() // '这是window的a'
A.printA() // '这是A对象的a'
在标准函数中,this引用哪个对象必须到函数被调用时才能确定。 在全局上下文中调用printA,this会指向window;在A中调用printA,this则会指向A对象。
在箭头函数中,this引用的是定义箭头函数的上下文, 还是用个例子来看下:
window.a = '这是window的a'
printA = () => {
console.log(this.a)
}
let A = {
a: '这是A对象的a',
}
A.printA = printA
printA() // '这是window的a'
A.printA() // '这是window的a'
因为printA是在window下定义的箭头函数,所以this一直指向的是window
基于上面的情况,可以想到我们日常开发中应用箭头函数特别多的一个地方,那就是回调函数。像我们平时使用addEventListener,setTimeout中的回调,从学习使用这些方法的时候,看到的传递的回调函数如果需要当前上下文中的变量之类的资源时,大都是用箭头函数,那是为什么呢???答案就是上面所说,箭头函数中的this会保存定义该函数时的上下文,使得回调的时候可以用this.xxx来调用相关的变量。(当然还有其他的方法例如bind指定this)
还有一个场景,那就是闭包,先上例子:
window.a = '这是window的a'
let A = {
a: '这是A对象的a',
printA() {
return function() {
console.log(this.a)
}
}
}
A.printA()() // '这是window的a'
这里涉及到,每个函数在被调用的时候都会自动创建this和arguments,而内部函数无法直接访问外部函数的这两个变量,所以输出了window下的a的值。如果想要正常显示A中的a,可以使用找个变量存一下外部函数的this(其实以前就很常见这种方法,但是没细想过为什么)
window.a = '这是window的a'
let A = {
a: '这是A对象的a',
printA() {
let that = this
return function() {
console.log(that.a)
}
}
}
A.printA()() // '这是A对象的a'
最后还有一点:严格模式下,定义在全局上下文中的this指向undefined
参考书籍《JavaScript高级程序设计》