MST
星途 面试题库

面试题:JavaScript中this关键字在普通函数与箭头函数中的区别

请详细阐述JavaScript中this关键字在普通函数和箭头函数中的绑定规则有何不同,并举例说明。
27.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

普通函数中this的绑定规则

  1. 默认绑定:在非严格模式下,当函数独立调用(不是作为对象的方法调用)时,this 指向全局对象(浏览器环境中是 window,Node.js 环境中是 global)。在严格模式下,this 会是 undefined
function foo() {
    console.log(this);
}
// 非严格模式下,在浏览器环境中会输出 window 对象
// 严格模式下,会输出 undefined
foo(); 
  1. 隐式绑定:当函数作为对象的方法调用时,this 指向调用该函数的对象。
const obj = {
    name: '张三',
    sayHello: function() {
        console.log(this.name);
    }
};
obj.sayHello(); // 输出 '张三',此时 this 指向 obj
  1. 显式绑定:通过 callapplybind 方法可以显式地指定函数中 this 的值。
    • call 方法接受多个参数,第一个参数是要绑定的 this 值,后面的参数依次作为函数的参数。
function greet(greeting) {
    console.log(greeting + ', ' + this.name);
}
const person = {name: '李四'};
greet.call(person, '你好'); // 输出 '你好, 李四',将 this 显式绑定到 person
- `apply` 方法与 `call` 类似,不同之处在于它接受一个数组作为参数,数组的元素作为函数的参数。
function sum(a, b) {
    return a + b;
}
const numbers = [2, 3];
const result = sum.apply(null, numbers); // 这里 this 绑定为 null,返回 5
- `bind` 方法会创建一个新的函数,这个新函数的 `this` 被绑定到 `bind` 方法的第一个参数,并且可以传递额外的参数。
function multiply(a, b) {
    return a * b;
}
const multiplyByTwo = multiply.bind(null, 2);
const result2 = multiplyByTwo(3); // 返回 6,this 绑定为 null
  1. new 绑定:当使用 new 关键字调用函数时,会创建一个新的对象,this 会指向这个新创建的对象。
function Person(name) {
    this.name = name;
}
const tom = new Person('Tom');
console.log(tom.name); // 输出 'Tom',此时 this 指向 tom

箭头函数中this的绑定规则

箭头函数没有自己的 this 绑定,它的 this 是继承自外层作用域的 this。它不会根据调用方式来改变 this 的指向,始终保持在定义时外层作用域的 this 值。

const obj2 = {
    name: '王五',
    getArrowFunction: function() {
        return () => {
            console.log(this.name);
        };
    }
};
const arrowFunc = obj2.getArrowFunction();
arrowFunc(); // 输出 '王五',这里箭头函数的 this 继承自外层函数 getArrowFunction 的 this,即 obj2
// 对比普通函数
const obj3 = {
    name: '赵六',
    getNormalFunction: function() {
        return function() {
            console.log(this.name);
        };
    }
};
const normalFunc = obj3.getNormalFunction();
// 在非严格模式下,下面这行代码会输出 undefined 或 window 对象上的 name 属性值(如果存在)
// 在严格模式下,会输出 undefined
normalFunc();