讨论this的指向笔记
概念
this
指的是当前执行上下文。
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
理解了上面this的定义。下面几种常见的场景也就不难理解了。
this在严格模式下。和非严格模式下表现也不尽相同。
全局环境中的this
无论是否在严格模式下,this都指向全局对象window
console.log(this === window); // true
普通函数中的this
非严格模式下。普通函数中的this指向全局对象,严格模式下this无指向。
- 非严格模式下,直接调用
test()
其实等同于window.test()
。 - 严格模式下,
test()
本身没有对象调用。
所以还是那个标准来判断 this始终指向调用它的对象
function test(){
return this;
}
// 非严格模式
console.log(test() === window) // true
// 严格模式
console.log(test() === undefined) // true
箭头函数中的this
在箭头函数中,this
永远指向与封闭词法环境的this
保持一致。
// 使用普通函数
const test = {
abc: function() {
return function() {
return this
}
}
}
let fn1 = obj.abc() // 等价于 function() { return this }
// 若在严格模式则为undefined
console.log(fn1() === window) // true
// 使用箭头函数
const test = {
abc: function fnA() { // abc
return () => this
}
}
let fn1 = obj.abc() // 此时确定了封闭词法环境。为obj
console.log(fn1() === window) // false
console.log(fn1() === obj) // true
在上面的例子中,一个赋值给了test.abc的函数fnA,返回了另一个箭头函数。因此,在 fn1 调用时,箭头函数的this被永久设置为test.abc(fnA)的this(test)。当返回的函数(箭头函数)被调用时,它this始终是最初设置的test
对象中的方法中的this
在上面的例子中,已经有关于对象中的this的指向。
- this一直指向调用该函数的对象。
const test = {
nub: 520,
f: function() {
return this.nub;
}
}
console.log(test.f()) // 520
class中的this
类内部总是严格模式。调用一个 this 值为 undefined 的方法会抛出错误。
- 构造函数中
this被绑定到正在构造的新对象
class Animal {
constructor({ name }) {
this.name = name
}
}
const bird = new Animal({
name: '鸟'
})
console.log(bird.name) // 鸟
- 普通方法中
和其他普通函数一样,方法中的 this 值取决于它们如何被调用。有时,改写这个行为,让类中的 this 值总是指向这个类实例会很有用
为了做到这一点,可在构造函数中绑定类方法。
class People {
constructor() {
this.say = this.say.bind(this)
}
say() {}
}
- 方法外部
call、apply、bind中的this
- this将永久地被绑定到了bind的第一个参数
- 在非严格模式下使用 call 和 apply 时,如果用作 this 的值不是对象,则会被尝试转换为对象。