2026-04-22 10:42:12
箭头函数与普通函数的核心区别体现在this绑定、构造函数能力、arguments对象处理及使用场景适配性上,具体如下:
1. this绑定机制不同普通函数:
动态绑定:this指向由调用方式决定。
直接调用时指向全局对象(非严格模式)或undefined(严格模式)。
作为对象方法调用时指向对象本身。
通过call/apply/bind可显式绑定this。
示例:const obj = { name: 'Tom', sayNameNormal: function() { console.log(this.name); } }; obj.sayNameNormal(); // 输出 "Tom"
箭头函数:
词法绑定:继承外层作用域的this,且不可通过调用方式改变。
问题场景:在对象方法中使用时,若外层作用域为全局,this可能丢失对象上下文。
示例:const obj = { name: 'Tom', sayNameArrow: () => { console.log(this.name); } }; obj.sayNameArrow(); // 输出 undefined(外层为全局作用域)
普通函数:
可作为构造函数,通过new创建实例,并初始化this指向新对象。
示例:function Person(name) { this.name = name; } const p = new Person('Alice'); // 正常创建实例
箭头函数:
无原型属性:缺少prototype,无法通过new调用,否则报错(is not a constructor)。
示例:const Animal = (name) => { this.name = name; }; const a = new Animal('Dog'); // 报错
普通函数:
拥有独立的arguments对象,包含所有传入参数,可通过索引或length访问。
示例:function sum() { console.log(arguments[0] + arguments[1]); } sum(2, 3); // 输出 5
箭头函数:
无独立arguments:引用外层函数的arguments,可能导致意外行为。
替代方案:使用ES6的rest参数(...args)显式收集参数。
示例:function foo() { const bar = () => { console.log(arguments); }; // 引用foo的arguments bar(); } foo(1, 2, 3); // 输出 [Arguments] { '0': 1, '1': 2, '2': 3 } // 推荐写法 const bar = (...args) => { console.log(args); };
适合箭头函数的场景:
无需动态this:如回调函数(setTimeout、事件监听)、数组方法(.map()、.filter())。
非构造函数:无需通过new实例化的场景。
简化代码:单行函数且无需arguments时,箭头函数更简洁。
示例:const numbers = [1, 2, 3]; const doubled = numbers.map(n => n * 2); // 简洁的箭头函数
应避免箭头函数的场景:
需要动态this:对象方法中需访问对象属性时。
构造函数:需定义类或工厂函数生成实例时。
依赖arguments:虽可用rest参数替代,但旧代码维护时需注意兼容性。
示例:const obj = { name: 'Tom', sayName: function() { const inner = function() { console.log(this.name); }; // 需用普通函数 inner.call(this); } };
箭头函数以词法绑定this、轻量级语法为特点,适合静态上下文;普通函数则凭借动态this、构造函数能力及独立arguments,在复杂逻辑中更灵活。选择依据:是否需要动态this、是否作为构造函数、是否依赖arguments,以及代码简洁性需求。