保姆级教学!JS 中 this 关键字的指向问题

112 阅读3分钟

前言

这篇文章主要来复述一下在JavaScript中的this的指向,在面试和工作中,都是需要了解的(ps:官方文档已经描述的很清楚了,我只是写了几个demo加深下印象😂)

this关键字

在面向对象语言中 this 表示当前对象的一个引用,而在 JavaScriptthis 会随着环境改变而改变的,下面我们来看下具体的🌰

对象方法中的 this

在对象方法中, this 指向调用它所在方法的对象,当然前提是我们没有去改变他的 this 指向(call、apply、bind)

 var Person = {
        lastName: 'stephen',
        fistName: 'curry',
        fullName: function () {
          console.log(this.lastName + '' + this.fistName, this, typeof this) 
        },
      }
 Person.fullName()

通过上述例子和介绍不难想出,这里的打印出来的 this 指向的是 Person 这个对象,this 的类型也就是 object 类型了

image.png

单独的使用 this

单独使用 this 关键字,在浏览器中它会指向 window 全局对象

   window.userName = 'zs'
   var x = this
   console.log(x, x.userName)

那么在全局对象中定义了 useName 属性,这里的 x 又指向全局,所以输出的自然是 zs 了

image.png

函数中的 this

函数中的 this 同样是指向全局的,那么在浏览器中就是指向 window 对象

window.a = 2
function add() {
    var a = 1
    console.log(this.a, this) // 2
}
add()

虽然我们在函数作用域中定义了 a 变量,但是由于 this 指向的 window 所以这里的打印的是2

image.png

特殊的,在 js 使用严格模式下,函数中的 this 指向的是 undefined

 'use strict'
  function add() {
    console.log(this)
  }
  add()

image.png

事件中的 this

在我们定义的事件中的 this 指向的是接受这个事件的元素,比如一个 button 按钮,为它添加点击事件,那么回调函数中的 this 就指向 button 这个元素

<button id="btn">点击</button>
<script>
 var btn = document.querySelector('#btn')
 btn.addEventListener('click', function () {
   console.log(this) // button元素
 })      
</script>

image.png

改变 this 指向

在官网中是这样介绍的

显示函数绑定:
在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。

那其实就是改变 this 的指向,具体要怎么实现呢,举个🌰,比如一个 person1 对象的一个方法返回 this.firtName + this.lastName但是这个对象没有这两个属性,而 person2 是有这两个属性的,这时候我们可以通过 call、apply、bind 方法将 this 指向改成指向 person2 ,这样 person1 中的方法返回的就是 person2 中的两个属性值,具体实现如下(这里通过 call 方法实现):

 var person1 = {
      fullName: function () {
       return this.firstName + this.lastName
      },
 }

 var person2 = {
    firstName: 'zs',
    lastName: '123',
 }

 const res = person1.fullName.call(person2)
 console.log(res)

那么根据上述所说的,我们不难得出最后的打印结果是zs123了

image.png

总结

通过👆🏻的介绍,我觉得应该会让懵懂的你有进一步对 this 指向问题的理解,当然我可能说的还是不够完整,还是欢迎各位大佬指出问题,进行修正,让文章变得更严谨!