this指向总结

2,179 阅读2分钟

前言

作为JS中最难理解的知识点之一,很多时候都很难分清到底指向的是啥,学了很久都还是处于一种云里雾里的状态。但又作为面试必考知识点之一,能够把这个问题研究透彻,对我们以后无论是面试还是工作都有很大用处。这次对this的使用方式做一个总结。

在构造函数中

let name='window'
function Person(name,age){
  this.name=name;
  this.age=age
}
let man=new Person('hkj',21)
console.log(man.name)   //hkj

对于new这种方式来说,this将永远绑定到被实例化的对象上

直接调用

var name='window'
function fun(){
  var name="name"
  console.log(this.name)
}
fun()       //window
var name='window'
function fun(){
  var name='fun'
  console.log(this.name)
}
let obj={
  fun:fun,
  name:'hkj'
}
let f=obj.fun
f()         //window
var name='window'
function hello(){
  var name='hello'
  console.log(this.name)
}
let obj1={
  name:'obj1',
  hello
}
let obj2={
  name:'obj2',
  obj1
}
let fun=obj2.obj1.hello;
fun()       //window

对于这直接调用方法来说,最后只要类似fun()这种调用,this最后都指向window

箭头函数

var name='hkj'
function fun(){
  var name="hkj1"
  return ()=>{
    var name='hkj2'
    console.log(this.name)          //hkj
    return ()=>{
      var name='hkj3'
      console.log(this.name)        //hkj
    }
  }
}
fun()()()

无论嵌套多少层箭头函数中的this与最外层非箭头函数this相同,最外层非箭头函数为fun(),其中的this指向window所以里面两个箭头函数也一样。

当做属性调用

var name='window'
function fun(){
  var name='fun'
  console.log(this.name)
}
let obj={
  fun:fun,
  name:'hkj'
}
obj.fun()       //hkj

被当做属性调用时,函数中this指向对最后一个调用函数的对象。这里指向obj,所以name为hkj

var name='window'
function hello(){
  var name='hello'
  console.log(this.name)
}
let obj1={
  name:'obj1',
  hello
}
let obj2={
  name:'obj2',
  obj1
}
obj2.obj1.hello()           //obj1

这里引用了多层,但用上面的方法判断,hello()前面是obj1,所以this指向obj1,最后name为obj1

定时器内this指向

var name='window'
function hello(){
  setTimeout(function(){
    console.log(this.name)
  }, 100);
}
let obj={
  name:'obj',
  hello
}
obj.hello()     //widow
var name='window'
function hello(){
  console.log(this.name)
}
let obj={
  name:'obj',
  hello
}
setTimeout(obj.hello,1000)          //window

按照上一种情况来说,此时的this应该指向的是obj,但setTimeout是一种特殊情况,setTimeout中的this都指向window。

解决办法:改为箭头函数,在setTimeout外层将this赋值给其他变量然后传入,或者call,aplly,bind等

  • 引用官方解释

call,apply,bind改变this指向

可以查看我下一篇博客:JS中的call、apply及bind

绑定优先级

new>call及其他两个函数>属性调用>直接调用