一、普通函数this指向
函数的this指向遵循一个基本原则:谁调用的函数,函数的this就指向谁,否则指向全局
示例
var name = 'window'
let obj = {
name: 'yuanzhi',
show1: function () {
console.log(this.name)
},
show2: function () {
return function () {
console.log(this.name)
}
}
}
// 问题1
obj.show1() // yuanzhi
// 问题2
obj.show2()() // window
问题1:因为show1方法是obj调用的,所以show1函数的this就指向了obj,所以this.name相当于obj.name,因此打印yuanzhi
问题2:首先show2方法是obj调用的,所以show2函数的this指向obj,但由于show2()方法返回了一个新的匿名函数fn,所以obj.show2()(),相当于fn(),而该匿名函数fn并没有指定的调用者,所以fn函数内部的this指向window,所以打印window
二、箭头函数this指向
箭头函数本身是没有 this,箭头函数 this 是定义箭头函数时父级作用域的 this,也就是说使用箭头函数时,箭头函数内部的 this,我们只需要看定义该箭头函数时,该箭头函数父级的 this 即可
示例
var name = 'window'
let obj = {
name: 'yuanzhi',
show1: ()=> {
console.log(this.name)
},
show2: ()=> {
return ()=> {
console.log(this.name)
}
}
}
// 问题1
obj.show1() // window
// 问题2
obj.show2()() // window
问题1:箭头函数本身是没有this的,所以我们并不关心谁调用的它,关键是看定义该箭头函数时,其父级作用域的this。上面的例子,定义箭头函数时,其父级作用域是全局,所以该箭头函数this指向的是window
问题2:首先show2函数返回一个匿名的箭头函数,该匿名箭头函数this指向的就是show2函数的this,而show2也是一个箭头函数,所以它的this指向window,所以返回的匿名的箭头函数this指向window
三、apply,call,bind三者的区别
- 三者都可以改变函数的this对象指向。
- 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window。
- 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入。
- bind 是返回绑定this之后的函数,便于稍后调用;apply 、call 则是立即执行 。