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>
相关推荐
JinSo5 小时前
我的2025年度总结:EasyEditor
前端·程序员
喝拿铁写前端9 小时前
前端开发者使用 AI 的能力层级——从表面使用到工程化能力的真正分水岭
前端·人工智能·程序员
wuhen_n10 小时前
LeetCode -- 15. 三数之和(中等)
前端·javascript·算法·leetcode
七月shi人10 小时前
AI浪潮下,前端路在何方
前端·人工智能·ai编程
非凡ghost10 小时前
MusicPlayer2(本地音乐播放器)
前端·windows·学习·软件需求
脾气有点小暴10 小时前
scroll-view分页加载
前端·javascript·uni-app
beckyye11 小时前
ant design vue Table根据数据合并单元格
前端·antd
布列瑟农的星空11 小时前
还在手动翻译国际化词条?AST解析+AI翻译实现一键替换
前端·后端·ai编程
土豆125011 小时前
Rust 错误处理完全指南:从入门到精通
前端·rust·编程语言