聊聊js的this指向

221 阅读2分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

前言

昨天刚好讲了箭头函数(文章在这里),里面有稍微讲了箭头函数的this指向,今天恰好把其它情况的this指向一起合并来讲讲。

this指向

this指向在js中要考虑很多情况,稍有不慎,就算工作很多年的大佬也会犯错。下面我分情况来说说。

1. new实例的this

new一个实例,this指向这个实例

function Fn (name) {
 this.name = name
 console.log(this)
}
new Fn('答案cp3') // Fn{name: '答案cp3'}

可以看到this是指向创建的实例

2. 作为对象的方法调用

普通函数作为对象的方法调用时,this是指向调用时的对象。

var name = '答案'
var obj = {
 name: 'cp3',
 getName: function () {
   console.log(this.name)
 }
}
obj.getName() // cp3

var name = '答案'
var obj = {
 name: 'cp3',
 getName: function () {
   console.log(this.name)
 }
}
let getName = obj.getName
getName() // 答案

解析:

  • 第一个例子的getName是在obj上调用的,this指向obj,所以打印出cp3
  • 第二个例子是把getName方法赋值给变量getName,然后再调用getName,此时getName 是等同于window.getName,此时this指向window,所以打印出cp3

这里是相对于普通函数,箭头函数的this不是这样指向的。下面来讲讲箭头函数的this。

3. 箭头函数的this

在我上一篇文章中说过,箭头函数没有自己的this,而是继承了它在定义时上层作用域的this,并且后面不会再次改变。

var name = '答案'
var obj = {
 name: 'cp3',
 getName:() => {
   console.log(this.name)
 }
}
obj.getName() // 答案

var name = '答案'
var obj = {
 name: 'cp3',
 getName: () => {
   console.log(this.name)
 }
}
let getName = obj.getName
getName.call({}) // 答案

由上面例子可以看出

  • objgetName是箭头函数,定义时上层作用域是window,所以调用是指向了window
  • 箭头函数的this指向在定义已经确定了,所以在后面的通过call方法想改变this指向也是不能改变的,还是指向window

4. 使用apply,call,bind方法调用

使用apply,call,bind方法可以显著改变函数的this指向,指向传入的第一个参数。

function getName () {
 console.log(this.name)
}
getName.call({
  name: '答案cp3'
}) // 答案cp3

调用call方法时,指向它的第一个对象{name: '答案cp3'}

5. 直接调用

当函数直接调用的时候,this的指向是window(非严格模式, 严格模式下是undefined)。

var name = '答案cp3'
function getName () {
 console.log(this.name)
}
getName() // 答案cp3

可以看到getName()方法直接调用,指向的是window对象。

总结

以上是我总结的js的this指向

主要是:

  • new实例的this
  • 作为对象的方法调用
  • 箭头函数的this
  • 使用apply,call,bind方法调用
  • 直接调用

希望对你们有帮助,如果有不理解,欢迎评论沟通。

感谢你们的阅读。