MST

星途 面试题库

面试题:JavaScript 箭头函数中 this 的特殊性及应用场景

阐述 JavaScript 箭头函数中 this 的绑定规则,与普通函数 this 绑定规则有何不同?并举例说明在哪些场景下适合使用箭头函数来处理 this 指向问题。
32.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

JavaScript箭头函数中this的绑定规则

  1. 词法作用域绑定:箭头函数没有自己的this,它的this是在定义时根据外层(词法层面)作用域来确定的,即继承自外层作用域的this。一旦确定,不会再被改变。

与普通函数this绑定规则的不同

  1. 普通函数
    • 默认绑定:在非严格模式下,独立调用的普通函数,this指向全局对象(浏览器中是window);严格模式下,thisundefined。例如:
    function normalFunction() {
        console.log(this);
    }
    normalFunction(); // 在非严格模式下,输出window
    'use strict';
    function normalFunctionStrict() {
        console.log(this);
    }
    normalFunctionStrict(); // 在严格模式下,输出undefined
    
    • 隐式绑定:当函数作为对象的方法调用时,this指向调用该方法的对象。例如:
    const obj = {
        name: 'test',
        sayName: function() {
            console.log(this.name);
        }
    };
    obj.sayName(); // 输出test
    
    • 显式绑定:通过callapplybind方法可以改变函数的this指向。例如:
    function greet() {
        console.log('Hello, '+ this.name);
    }
    const person1 = {name: 'Alice'};
    const person2 = {name: 'Bob'};
    greet.call(person1); // 输出Hello, Alice
    greet.apply(person2); // 输出Hello, Bob
    const greetBob = greet.bind(person2);
    greetBob(); // 输出Hello, Bob
    
  2. 箭头函数:如上述所说,箭头函数this继承自外层作用域,不会被callapplybind等方法改变this指向。例如:
const obj = {
    name: 'test',
    arrowFunction: () => {
        console.log(this.name);
    }
};
obj.arrowFunction(); // 这里的this指向全局对象(非严格模式下是window),因为箭头函数定义时的外层作用域是全局作用域,所以不会输出test

适合使用箭头函数来处理this指向问题的场景

  1. 回调函数:在事件处理、数组方法(如mapfilterforEach等)的回调函数中,通常适合使用箭头函数。因为这些场景下我们希望this保持外层作用域的指向。例如:
const numbers = [1, 2, 3];
const self = this;
numbers.map(function(num) {
    return num * self.factor; // 这里需要保存外层的this,写法较繁琐
});
// 使用箭头函数
const numbers = [1, 2, 3];
const factor = 2;
numbers.map(num => num * factor); // 简洁明了,this指向外层作用域,这里factor可以直接访问
  1. 简化对象方法中使用this的复杂逻辑:如果对象方法内部需要使用this,且没有改变this指向的需求,使用箭头函数可以简化代码。例如:
const myObject = {
    data: [1, 2, 3],
    sum: function() {
        return this.data.reduce((acc, num) => acc + num, 0);
    }
};
console.log(myObject.sum()); // 直接使用箭头函数在reduce回调中,简洁且this指向正确