js中的this指向

在 JavaScript 中,this 的指向是一个核心概念,其值取决于函数的调用方式,而非定义位置。以下是常见场景的详细说明:


1. 全局环境

  • 在全局执行上下文中(非严格模式),this 指向全局对象:
    console.log(this); // 浏览器中: window, Node.js中: global
    
  • 严格模式下全局 thisundefined
    "use strict";
    console.log(this); // undefined
    

2. 函数调用

  • 普通函数
    function show() {
      console.log(this); // 非严格模式: window/global
    }
    show();
    
  • 严格模式
    "use strict";
    function show() {
      console.log(this); // undefined
    }
    show();
    

3. 对象方法调用

  • 当函数作为对象方法调用时,this 指向调用该方法的对象
    const user = {
      name: "Alice",
      greet() {
        console.log(this.name); // "Alice"
      }
    };
    user.greet(); // this = user
    

4. 构造函数调用

  • 使用 new 关键字时,this 指向新创建的实例
    function Person(name) {
      this.name = name; // this = 新对象
    }
    const bob = new Person("Bob");
    

5. 显式绑定

  • 通过 call(), apply(), bind() 强制指定 this
    function logName() {
      console.log(this.name);
    }
    
    const obj1 = { name: "Alice" };
    const obj2 = { name: "Bob" };
    
    logName.call(obj1);    // "Alice" (this = obj1)
    logName.apply(obj2);   // "Bob"   (this = obj2)
    
    const boundFn = logName.bind(obj1);
    boundFn();            // "Alice" (永久绑定)
    

6. 箭头函数

  • 没有自己的 this,继承外层作用域的 this(定义时确定):
    const user = {
      name: "Alice",
      greet: () => {
        console.log(this.name); // 指向全局(非严格模式: window.name)
      }
    };
    user.greet(); // 输出空(全局无name)
    
  • 解决回调中 this 丢失问题:
    const timer = {
      count: 0,
      start() {
        setInterval(() => {
          console.log(this.count++); // this 正确指向 timer
        }, 1000);
      }
    };
    timer.start();
    

7. 事件处理函数

  • DOM 事件中 this 指向触发事件的元素
    button.addEventListener("click", function() {
      console.log(this); // <button> 元素
    });
    

8. 回调函数中的陷阱

  • 回调函数可能丢失原始 this
    const user = {
      name: "Alice",
      greet() {
        setTimeout(function() {
          console.log(this.name); // 错误!this 指向全局
        }, 100);
      }
    };
    user.greet();
    
  • 解决方案
    • 使用箭头函数:setTimeout(() => console.log(this.name), 100);
    • 保存 thisconst self = this;
    • 使用 bindsetTimeout(this.greet.bind(this), 100);

关键总结

场景 this 指向
全局环境 全局对象(非严格模式)/ undefined(严格模式)
对象方法 调用该方法的对象
构造函数 新创建的实例
call/apply/bind 指定的对象
箭头函数 定义时的外层作用域 this
DOM 事件 触发事件的元素
回调函数(未处理) 全局对象 / undefined

理解 this 的关键是分析函数的调用方式,而非定义位置。箭头函数和显式绑定是控制 this 的常用手段。

posted @ 2025-06-24 16:41  张浩伟  阅读(29)  评论(0)    收藏  举报