JavaScript中this的指向!!!

205 阅读2分钟

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高级程序设计》