[路飞]每日一答:介绍一下this指向的4种形式?

116 阅读3分钟

介绍一下 this 指向的 4 种形式?

这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

面向对象语言中 this 表示当前对象的一个引用。在 javascript 中 this 的指向总是在不同的环境,不同的语法下产生不同的变化,这也就产生了 this 指向的不同形式。

但归根结底 this指向的都一定是方法所归属的对象,指向取决于其调用位置。

普通函数以及嵌套函数中的 this

如果一个函数存在于全局中,他不属于任何对象,那么这个 this会指向全局,或者说是指向 window

function logName() {
  console.log(this.name);
}
name = "ouda";
logName(); // ouda

上述代码中定义了全局变量 name, 在普通函数 logName中,存在于全局,那么函数中的this便指向全局,即 window,那么函数中所打印的 name便是全局变量name

多重函数前套情况:

function logName() {
  function logName2() {
    console.log(this.name);
  }
  logName2()
}
name = "ouda";
logName(); // ouda

结果依然是this指向全局变量,说明this的指向和函数嵌套个数是无关的。

对象中的 this

const person = {
  name: 'test',
  logName: function () {
    console.log(this.name)
  }
}
name = 'ouda'

person.logName() // test

在对象中,this并没有打印全局变量ouda,而是打印了对象的内部属性 test,说明在对象中的方法中,this指向的是对象本身的实例。

再看一例:

const logName = function () {
  console.log(this.name)
}

const person = {
  name: 'test',
  logName
}
name = 'ouda'

logName() // ouda
person.logName() // test

因为调用的上下文不同,即使是同一个方法,他们所致的结果也是不一样的.

构造函数和Class中的 this

function Person(name) {
  this.name = name
}
Person.prototype.logName = function () {
  console.log(this.name)
}

this.name = 'ouda'
console.log(this.name) // ouda
new Person('test').logName() // test

在上述中有, Person 构造函数中的 this 指向的是构造函数产生的实例对象,这也是我们对实例对象初始化传参的重要过程。Person.prototype.logName函数中,所指向的依然是Person构造函数产生的对象。所以他们所指向的都是对象中的属性 name

class Person {
  constructor(name) {
    this.name = name
  }
  logName() {
    console.log(this.name)
  }
}

new Person('ouda').logName() // ouda

在 class 和 上述一致,指向的都是构造出来的对象实例。所以在 class constructor 中等同于 function 构造函数。

call、apply、bind 方法中的 this

function logName() {
  console.log(this.name)
}

logName() // undefined
logName.apply({ name: 'ouda' }) // ouda
logName.bind({ name: 'ouda' })() // ouda
logName.call({ name: 'ouda' }) // ouda

原本在函数 logNamethis指向是全局,但是并没有 name变量,所以打印的是 undefined, 但是通过 apply, bind , call 调用之后, this 的指向发生了改变,实际上是指向了 logName方法的调用者。

严格模式下this

"use strict"
name = 'ouda'
function logName() {
  console.log(this.name)
}
logName() // undefined

在严格模式下,普通函数 this 指向的是 undefined,未定义。

总结

  • 在方法中,this 表示该方法所属的对象。
  • 如果单独使用,this 表示全局对象。
  • 在构造函数中,this 表示构造函数所产生的实例
  • 在函数中,this 表示全局对象。
  • 在函数中,在严格模式下,this 是未定义的(undefined)。
  • 在事件中,this 表示接收事件的元素。
  • 类似 call() 和 apply() 方法可以将 this 引用到任何对象。