网站
引入
学了函数之后,经常会看到 this 这个关键字。
this 的指向不是固定的,它会随着函数的调用方式变化。这是 JS 里最容易搞混的地方之一,但只要记住几条规则就能判断。
正文
定义
定义
this是一个关键字,指向当前调用函数的那个对象。
this 的值不是在函数定义时确定的,而是在函数被调用时决定的。
全局上下文
在全局作用域中,this 指向 window(浏览器环境)。
console.log(this === window);普通函数调用
普通函数调用时,this 也指向 window。
function show() {
console.log(this);
}
show();这里 show() 等于 window.show(),所以 this 是 window。
对象方法调用
当函数作为对象的方法被调用时,this 指向调用它的对象。
let user = {
name: "Tom",
sayHello() {
console.log(this.name);
}
};
user.sayHello();这里 user.sayHello() 的 this 是 user。
但要注意,如果把方法单独取出来调用,this 会变。
let user = {
name: "Tom",
sayHello() {
console.log(this.name);
}
};
let fn = user.sayHello;
fn();这里 fn() 是普通函数调用,this 变成了 window。
构造函数
用 new 调用函数时,this 指向新创建的对象。
function User(name) {
this.name = name;
}
let user1 = new User("Tom");
let user2 = new User("Jack");
console.log(user1.name);
console.log(user2.name);user1 和 user2 是不同的对象,各自的 this 指向自己。
箭头函数
箭头函数没有自己的 this,它会从外层作用域继承。
let user = {
name: "Tom",
sayHello() {
let arrow = () => {
console.log(this.name);
};
arrow();
}
};
user.sayHello();箭头函数里的 this 和 sayHello 里的 this 一样,都是 user。
这也是箭头函数常用的原因之一:回调函数里用箭头函数,this 不会乱。
事件处理函数
在 DOM 事件处理函数中,this 指向触发事件的元素。
<button id="btn">点击</button>let btn = document.querySelector("#btn");
btn.addEventListener("click", function () {
console.log(this);
console.log(this.textContent);
});点击按钮后,this 就是 btn 这个元素。
注意:如果事件处理函数用箭头函数,this 不会指向元素。
btn.addEventListener("click", () => {
console.log(this);
});这里 this 是外层作用域的 this,通常是 window。
call、apply、bind
可以用这三个方法手动指定 this 指向。
function sayHello() {
console.log("你好," + this.name);
}
let user = { name: "Tom" };
sayHello.call(user);
sayHello.apply(user);
let bound = sayHello.bind(user);
bound();call 和 apply 立即执行,bind 返回一个新函数,稍后调用。
常见场景
| 调用方式 | this 指向 |
|---|---|
| 全局作用域 | window |
| 普通函数调用 | window |
| 对象方法调用 | 调用它的对象 |
new 构造函数 | 新创建的对象 |
| 箭头函数 | 外层作用域的 this |
| 事件处理函数 | 触发事件的 DOM 元素 |
call/apply/bind | 手动指定的对象 |
特点
this的值在函数调用时决定,不是定义时决定- 普通函数调用时
this指向window - 对象方法调用时
this指向调用者 - 箭头函数不绑定自己的
this call、apply、bind可以手动指定this- 事件处理中
this指向触发事件的元素
理解
可以把 this 理解为:谁在叫我,我就代表谁。
user.sayHello() 是 user 在调用,this 就是 user。
new User() 是 new 创建的新对象在调用,this 就是那个新对象。
btn.addEventListener 里,按钮在调用,this 就是按钮。
最容易出错的地方是:把方法取出来单独调用,this 就变了。遇到这种情况,要么用 bind 绑定,要么换成箭头函数。
引出
理解了 this 之后,可以继续学习 JS apply 和 call,掌握手动控制 this 指向的方法。
也可以结合 JS 箭头函数 理解为什么箭头函数里 this 不会变。