Skip to content

JavaScript 中的 this #10

Open
Open
@myLightLin

Description

@myLightLin

为什么要有 this

在 JS 里,执行上下文包含了全局执行上下文,函数执行上下文和 eval 执行上下文。每个执行上下文里都包含了变量环境、词法环境还有 this。这就是说,this 对应的有全局上下文 this (window),函数中的 this (分多种情况) 还有 eval 里的 this。正是因为执行上下文有多个,所以才需要有一个机制来准确地指向当前代码运行时的上下文,这就是 this。

全局上下文的 this

也就是 window,比如下面这段代码:

function foo() {
  console.log(this)
}
foo()

执行 foo 函数后打印的 this 就是全局 window 对象。

函数中的 this

this 取决于函数是在哪里调用的,看下面这段代码:

var name = '李四'
var bar = {
    name: '张三',
    getName: function() {
      console.log(this.name)
    }
}
var foo = bar.getName
foo()   // 全局环境下调用,this 指向 window,打印李四
bar.getName()  // 通过对象的方法调用,this 指向该对象,打印张三

除此之外,还有构造函数中的 this:

function foo(name) {
  this.name = name
}
var f = new foo('张三')
f.name  // 打印张三

在构造函数里,this 指向对应构造函数的实例

显式指定 this 的指向

通过 callapplybind 方法可以改变函数的 this 指向,注意,如果传入了 null 或 undefined,则值被忽略,this 依然指向全局对象 window

怎么判断分析 this 的指向

优先级:new 构造函数调用 > call,apply, bind > bar.foo() 对象方法调用 > 默认情况下 window

this 的缺陷

嵌套函数中的 this 不会从外层函数继承

比如我们在函数 A 中嵌套了函数 B,对于普通函数来说,B 的 this 是跟 A 不同的,所以经常会在代码里看到 const self = this 来存储当前环境的 this,所幸的是,ES6 的 箭头函数 解决了这个问题。

默认情况下,this 指向全局 window 对象

这会带来很多不可控的情况,毕竟谁也不想不知不觉就修改了全局对象里的属性或方法(doge。解决方法是开启严格模式,在严格模式下,this 指向 undefined

总结

在 JS 里,this 的指向有以下几种情况:

  • 全局环境下执行,指向 window 对象
  • 通过对象方法调用,指向该对象
  • 通过构造函数调用,指向所在实例
  • 默认情况下,非严格模式指向 window,严格模式下指向 undefined
  • 一个特例,箭头函数没有自己的 this,它的 this 取决于函数定义时的上下文

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions