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>
相关推荐
liliangcsdn2 分钟前
mac mlx大模型框架的安装和使用
java·前端·人工智能·python·macos
CssHero5 分钟前
基于vue3完成领域模型架构建设
前端
PanZonghui8 分钟前
用项目说话:我的React博客构建成果与经验复盘
前端·react.js·typescript
挽淚11 分钟前
JavaScript 数组详解:从入门到精通
javascript
言兴12 分钟前
教你如何理解useContext加上useReducer
前端·javascript·面试
sunbyte15 分钟前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | GoodCheapFast(Good - Cheap - Fast三选二开关)
前端·javascript·css·vue.js·tailwindcss
前端的日常17 分钟前
网页视频录制新技巧,代码实现超简单!
前端
前端的日常18 分钟前
什么是 TypeScript 中的泛型?请给出一个使用泛型的示例。
前端
今禾19 分钟前
一行代码引发的血案:new Array(5) 到底发生了什么?
前端·javascript·算法
ccc101822 分钟前
老师问我localhost和127.0.0.1,有什么区别?
前端