一分钟带你深入理解JS中的this

105 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情

前言

在JS中,this是最常用的关键字了,而且现在使用 vue 、 react 之后,this还分为 windows、vue等。

本文将带你一起彻底理解this关键字,希望对你未来的学习有一定的帮助。

啥是this,为啥要用this

😛 this关键字是JS中最复杂的机制之一,主要是它比较特别,自动定义在所有函数作用域中。

😝 根据下面的代码来理解一下为啥要用this

function identify(){
    return this.name.toUpperCase()
}

function speak(){
    var greeting = "Hello! I'm " + identify.call(this)
    console.log(greeting)
}

var me = {
    name: 'juejin'
}

var you = {
    name: 'xitu'
}

identify.call(me)    // JUEJIN
identify.call(you)    // XITU

speak.call(me)    // Hello! I'm JUEJIN
speak.call(you)    // Hello! I'm XITU
  • 这段代码中不同的上下文对象me、you都可以重复使用函数identify、speak

🤨 如果我们不使用this关键字,那么我们就需要给 identify()speak() 传入一个单独的上下文对象

function identify(content){
    return content.name.toUpperCase()
}

function speak(content){
    var greeting = "Hello! I'm " + identify.call(content)
    console.log(greeting)
}

😏 对比两段代码,不难发现 this 关键字是一种更优雅的方式

😏 随着我们的代码越来越复杂,如果一直使用 content 这种传递参数的方式到函数里面的话,就会让上下文代码变得越来越混乱

this作用域

😪 this指向函数作用域?这个问题就有点复杂了,因为在某些情况下是正确的,但是在一些特殊的情况下它却是错误的。

function foo(){
    var a = 1
    this.bar()
}

function bar(){
    console.log(this.a)
}

foo()
  • 这段代码是某大厂出的面试题,大家可以思考一下这个例子中输出的是啥。

输出:ReferenceError:a is not defined

🧐 是的,你没有看错,就是报错了

  • 第一点错误

    • 这段代码试图通过this.bar()来引用bar()函数,这是不可能成功的。
    • 调用bar()函数最自然的方法就是去掉前面的 this
  • 第二点错误

    • 这段代码中还试图通过this来连通foo()bar(),从而让bar()可以访问foo()中的变量 a

每当你要把 this关键字 和 词法作用域 混合使用时,一定要牢记并提醒自己,这是不可能实现的。

如何理解this

🤠 this 是在运行时进行绑定的,而不是在JS编译时绑定的,而它的上下文就取决于函数调用时的一些条件。

🤠 this 的绑定和函数声明的位置没有任何关系,只是取决于函数的调用方式

总结一下

对于前端开发者来说,this的绑定一直让人很困惑,所以学习this时不要被一些不正确的解释误导,而是需要正确的理解this