JavaScript 中函数的 this 指向问题

在 JavaScript 中,this 关键字的值是由函数调用的上下文决定的。this 的值在不同的场景中会有所不同,理解这些场景非常重要。

小结:

  • 当函数作为普通函数调用时,this 在非严格模式下指向全局对象(浏览器中是 window,Node.js 中是 global),在严格模式下则是 undefined。
  • 当函数作为对象的普通函数调用时,this 指向该对象
  • 当作为构造函数调用: this 指向新创建的对象。
  • 在一个对象的方法中定义了一个箭头函数,箭头函数的 this 就是定义这个箭头函数的方法的 this,而不是调用这个箭头函数时的 this
  • 箭头函数: this 继承自外部作用域,不会动态绑定。
  • call() / apply() / bind(): 用于显式绑定 this

1. 全局上下文中的 this

  • 在全局执行环境中(非严格模式),this 指向 全局对象(在浏览器中是 window,在 Node.js 中是 global)。
  • 在严格模式下,this 会是 undefined
console.log(this); // 在浏览器中输出 window,在 Node.js 中输出 global

2. 普通函数中的 this

在普通函数调用时,this 会指向 全局对象(在非严格模式下)。在严格模式下,thisundefined

 function show() { console.log(this); return 1;}
 show();        // 输出 window 
 let a1 = show()// 输出 window 
 console.log("a1:",a1);  //输出:1; (解析:输出值为show中return的值,没有return则为undefined)

3. 对象方法中的 this

当函数作为对象的方法调用时,this 会指向调用该方法的对象。

const obj = {
        name: "Alice",
        greet: function () {
          console.log(this.name);
        },
      };
obj.greet(); // 输出 Alice

4. 构造函数中的 this

当函数作为构造函数使用时(即通过 new 关键字调用),this 会指向新创建的对象。

function Person(name) {
    this.name = name;
}
const person1 = new Person('Tom');
console.log(person1.name);  // 输出 Tom

5. 箭头函数中的 this

箭头函数没有自己的 this,它会继承其外部环境(词法作用域)的 this。因此,在箭头函数中,this 是在定义时确定的,而不是在调用时确定的。

// 对象内的箭头函数
const obj = { name: 'Alice', greet: () => { console.log(this,'和',this.name); } }; obj.greet(); // 输出window和''(空);因为箭头函数中的 this 继承自外部环境的 this(全局对象),全局对象下并没有name变量
// 对象方法中的箭头函数
const obj = {
     a: 10,        
     fun: function () {
          const way = () => {
              console.log(this);
           };
          way(); 
       },
};
obj.fun()  //输出输出 obj对象  {a: 10, fun: ƒ}

 6. call() 和 apply()方法

  • call()apply() 方法允许显式地指定函数执行时 this 的值。
  • call() 接受一组参数,而 apply() 接受一个数组参数。
function greet() {
  console.log(this.name);
}
const person = { name: 'Bob' };
greet.call(person);  // 输出 Bob
greet.apply(person);  // 输出 Bob

 7. bind()方法

bind() 方法返回一个新函数,允许你显式绑定 this。无论这个函数以后如何被调用,this 都会指向 bind() 中指定的对象。

const person = { name: 'Tom' };
function greet() {
  console.log(this.name);
}
const boundGreet = greet.bind(person);
boundGreet();  // 输出 Tom

8. 事件处理函数中的 this

const button = document.querySelector('button');
button.addEventListener('click', function() {
    console.log(this);  // 输出点击的 button 元素
});

如果用箭头函数,它不会指向 DOM 元素,而是继承外部的 this

button.addEventListener('click', () => {
    console.log(this);  // 输出外部作用域的 this (可能是 window 或 undefined)
});

其他文章:前端面试之彻底搞懂this指向

posted @ 2025-01-10 11:48  灬小呱灬  阅读(63)  评论(0)    收藏  举报