setTimeout回调函数 this指向问题

本文主要介绍setTimeout的回调函数的this指向问题

例子1:回调函数是一个普通函数

setTimeout 的回调函数是一个普通函数,而不是箭头函数,因此它有自己的上下文,this 指向全局对象(在浏览器中是 window 对象)

js 复制代码
 var name = "我是全局的name";  // 注意这里的name必须用var声明,不可以是let,用let打印出来的就是undefined
 // 因为var可以让a是全局作用域,但是let不可以,所以访问对象不存在的属性返回undefined
    const obj = {
      name: "我是局部的name:John",
      greet: function () {
        setTimeout(function () {
          console.log("this", this); // window
          console.log(" this.name:" + this.name);
        }, 1000);
      },
    };

    obj.greet();


参考文章

例子2:回调函数是箭头函数

箭头函数的this继承自外部的greet()

js 复制代码
     var name = "我是全局的name";
    const obj = {
      name: "John",
      greet: function () {
        setTimeout(() => {
          // 因为是箭头函数,所以往上找,所以是greet的this,
          // 那么greet的this是什么呢? 谁调用它就是谁,所以是obj
          // 所以 这里的this是obj
          console.log("this", this); // obj
          console.log(" this.name:" + this.name); // 输出:Hello, John
        }, 1000);
      },
    };
    obj.greet();

例子3:回调函数是匿名函数

但是在匿名函数中,因为匿名函数的执行环境具有全局性,所以它的this一般指向window。

js 复制代码
  var name = "我是全局的name";
    const obj = {
      name: "John",
      greet: function () {
        setTimeout(function () {
          console.log("this", this);
          console.log(" this.name:" + this.name);
        }, 1000);
      },
    };
    obj.greet();

解决第一个例子中的this问题:使用bind

javascript 复制代码
const obj = {
  name: 'John',
  greet: function() {
    setTimeout(function() {
      console.log(this.name);
    }.bind(this), 1000);
  }
};

obj.greet(); // 输出:Hello, John

在这个例子中,.bind(this)this 绑定到了 setTimeout 内部的回调函数中,确保 this 在回调函数内部指向 obj 对象。

当然,也可以用例子2的箭头函数方法来解决

扩展案例

主要看 user.sleep();的this指向!!

js 复制代码
<script>
    console.log(this); // 此处为 window
    // 箭头函数
    const sayHi = function () {
      console.log("sayHi", this);
    };
    // 普通对象
    const user = {
      name: "小明",
      // 该箭头函数中的 this 为函数声明环境中 this 一致
      walk: () => {
        console.log("walk", this); // 箭头函数本身没有this,所以往上找,
        // user是对象,也没有this,所以继续向上找,所以最后是window
      },

      sleep: function () {
        let str = "hello";
        console.log("sleep的function", this); // obj
        let fn = () => {
          console.log(str);
          console.log("sleep里面的fn", this); // 该箭头函数中的 this 与 sleep 中的 this 一致
          // obj
        };
        // 调用箭头函数
        fn();
      },
    };

    // 动态添加方法
    user.sayHi = sayHi;

    // 函数调用
    user.sayHi();
    user.sleep();
    user.walk();
  </script>
相关推荐
程序软件分享7 小时前
多语言DAPP综合盘交易所系统源码搭建剖析
vue.js·金融·开源
GuWenyue7 小时前
等AI回复卡顿到劝退?Vue3+DeepSeek流式输出实战,70行代码实现打字机效果
前端·人工智能·客户端
Jackson__7 小时前
AI Agent 的能力从哪里来?一文讲清后训练、上下文学习和外部能力
前端·agent·ai编程
默_笙7 小时前
🎉 AI 项目里为什么需要 BFF?因为我实在不想在前端处理二进制流
前端·javascript
Revolution617 小时前
改一个订单筛选,为什么要在六个目录里来回找,前端项目目录到底要怎么拆
前端·前端工程化
阳光是sunny7 小时前
LangGraph高级教程:Multi Schema多状态管理详解
前端·人工智能·后端
mCell9 小时前
从 TodoList 到 Microsoft To Do:全栈工程师到底要管什么?
前端·编程语言·全栈
阳光是sunny9 小时前
LangGraph实战教程:状态管理与`graph.invoke`入参深度解析
前端·人工智能·后端
神奇小汤圆9 小时前
深入解析 Flink Kafka Connector:原理、配置与最佳实践
前端·后端
科技之门9 小时前
百公里管网漏损分级定位实战方案2026
前端·人工智能·算法