Open
Description
为什么要有 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 的指向
通过 call
,apply
,bind
方法可以改变函数的 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 取决于函数定义时的上下文