在 JavaScript 中,this
关键字是指当前正在运行代码时所在的环境对象。
this
的值取决于函数的调用方式:
- 默认情况下,指全局对象。
- 在函数中,当不处于严格模式时,它引用全局对象
window
;当处于严格模式时,它将是undefined
。 - 在箭头函数中,
this
保留封闭词法上下文的this
值。 - 在对象方法中,
this
指调用该方法的对象。 - 在构造函数调用中,
this
绑定到正在构造的新对象。 - 在事件处理程序中(DOM 事件绑定),
this
绑定到监听器所在的元素。 call/apply/bind
可以显式绑定this
的指向
在全局执行上下文中,this
指的是全局对象(浏览器中的 window
)。
console.log(this === window) // true
在非严格模式下,函数的 this
引用全局对象。
function func() {
return this
}
console.log(func() === window) // true
在严格模式('use strict'
)下,如果在进入执行上下文时未设置,则函数的 this
将以 undefined
代替全局对象。
'use strict'
function func() {
return this
}
func() // undefined
如果在调用函数时使用 new
关键字,那么函数中的 this
指的是一个全新的对象。
function User() {
return this
}
User() // 返回 window 对象
function User(name) {
this.name = name
}
new User('lio') // User {name: "lio"}
new User('lion') // User {name: "lion"}
可以看看 new
的原理。
如果函数作为一个对象的方法调用,则 this
是指该方法被调用的对象。
const user = {
name: 'lio',
age: 18,
run() {
return this.name
}
}
user.run() // "lio"
这适用于在对象的原型链的任何地方定义的方法(即自己的和继承的方法)。
如果是 ES6 的箭头函数,在箭头函数内部访问到的 this
都是从外部获取的。this
值取决于外部不是箭头函数的函数。
const func = () => this
console.log(func() === window) // true
const user = {
name: 'lio',
age: 18,
run() {
const getUser = () => this.name
return getUser()
},
foo: () => this
}
console.log(user.run()) // lio
console.log(user.foo() === window) // true
注意:箭头函数没有自己的
this
,arguments
和super
等。
在事件处理程序中使用时,它指的是放置监听器的元素。
btn.addEventListener('click', function () {
console.log(this) // 返回 <button> DOM 对象
})
// 使用箭头函数返回 window 全局对象
btn.addEventListener('click', () => {
console.log(this) // 返回 window 全局对象
})
如果使用 apply
、call
或 bind
来调用/创建函数,则函数中的对象就是作为参数传入的对象。
使用 Function.prototype.bind()
从现有函数返回一个新函数,其中该函数永久绑定到 bind()
的第一个参数。
function func() {
console.log(this)
}
const user = {
name: 'lio',
age: 18
}
const v = func.bind(user)
v() // {name: "lio", age: 18}
使用 Function.prototype.call()
或 Function.prototype.apply()
将被调用函数的 this
绑定到这两个函数的第一个参数。
function func() {
console.log(this)
}
const user = {
name: 'lio',
age: 18
}
func() // Window { ... }
func.apply(user) // {name: "lio", age: 18}