一篇文章搞懂JavaScript中函数的this到底指向谁?

209 阅读1分钟

首先总结

  • 如果看到this,下意识的去找作用域中最近的所属funtion,看他是怎么被执行的
  • this取决于function被调用的方式,而不是定义的方式
  • function被调用分为以下几种方式
    1.作为函数调用,即:foo(),指向全局对象(window,node全局对象,模块化作用域)
    2.作为方法调用,例:foo.bar(),指向调用这个方法的对象
    3.作为构造函数调用,即: new Foo(),指向一个新对象,Foo{}
    4.特殊调用,例:foo.apply()/foo.call(),指向参数制定成员
    
  • 有小伙伴说箭头函数呢?箭头函数没有改变this的作用,因此箭头函数内的this指向参照上一条

还不太了解?以下几个例子分别在浏览器console及vscode中运行,看看打印的是什么?最好先思考一下,再验证

var name = 'outer'
const person = {
   name: 'inner',
   subName: () => {
       console.log(this)
   },
   inner () {
       console.log(this)
       setTimeout(() => {
           console.log(this)
       }, 1000)
       setTimeout(function() {
           console.log(this)
       }, 1500)
   }
}

// #1
// person.inner()

// #2
// let fn = person.inner
// fn()

// #3
// person.subName()

// #4
// let fn1 = person.subName
// fn1()
function foo () {
   console.log(this)
}

const obj = {
   foo() {
     console.log(this)
   }
}
obj.foo()
let fn = obj.foo
fn()

const obj1 = {
   foo () {
       function bar () {
           console.log(this)
       }
       bar()
   },
   foo1 () {
       const bar1 = () => {
           console.log(this)
       }
       bar1()
   }
}
obj1.foo() // 这里想不明白可以参照规则3-1
obj1.foo1() // 箭头函数内this往上找function,找到foo1,看foo1的调用方式