网站

JavaScript this - W3School

this - JavaScript | MDN

引入

学了函数之后,经常会看到 this 这个关键字。

this 的指向不是固定的,它会随着函数的调用方式变化。这是 JS 里最容易搞混的地方之一,但只要记住几条规则就能判断。

正文

定义

定义

this 是一个关键字,指向当前调用函数的那个对象

this 的值不是在函数定义时确定的,而是在函数被调用时决定的。

全局上下文

在全局作用域中,this 指向 window(浏览器环境)。

console.log(this === window);

普通函数调用

普通函数调用时,this 也指向 window

function show() {
  console.log(this);
}
 
show();

这里 show() 等于 window.show(),所以 thiswindow

对象方法调用

当函数作为对象的方法被调用时,this 指向调用它的对象

let user = {
  name: "Tom",
  sayHello() {
    console.log(this.name);
  }
};
 
user.sayHello();

这里 user.sayHello()thisuser

但要注意,如果把方法单独取出来调用,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);

user1user2 是不同的对象,各自的 this 指向自己。

箭头函数

箭头函数没有自己的 this,它会从外层作用域继承。

let user = {
  name: "Tom",
  sayHello() {
    let arrow = () => {
      console.log(this.name);
    };
    arrow();
  }
};
 
user.sayHello();

箭头函数里的 thissayHello 里的 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

callapplybind

可以用这三个方法手动指定 this 指向。

function sayHello() {
  console.log("你好," + this.name);
}
 
let user = { name: "Tom" };
 
sayHello.call(user);
sayHello.apply(user);
 
let bound = sayHello.bind(user);
bound();

callapply 立即执行,bind 返回一个新函数,稍后调用。

常见场景

调用方式this 指向
全局作用域window
普通函数调用window
对象方法调用调用它的对象
new 构造函数新创建的对象
箭头函数外层作用域的 this
事件处理函数触发事件的 DOM 元素
call/apply/bind手动指定的对象

特点

  • this 的值在函数调用时决定,不是定义时决定
  • 普通函数调用时 this 指向 window
  • 对象方法调用时 this 指向调用者
  • 箭头函数不绑定自己的 this
  • callapplybind 可以手动指定 this
  • 事件处理中 this 指向触发事件的元素

理解

可以把 this 理解为:谁在叫我,我就代表谁

user.sayHello()user 在调用,this 就是 user

new User()new 创建的新对象在调用,this 就是那个新对象。

btn.addEventListener 里,按钮在调用,this 就是按钮。

最容易出错的地方是:把方法取出来单独调用,this 就变了。遇到这种情况,要么用 bind 绑定,要么换成箭头函数。

引出

理解了 this 之后,可以继续学习 JS apply 和 call,掌握手动控制 this 指向的方法。

也可以结合 JS 箭头函数 理解为什么箭头函数里 this 不会变。