javascript函数怎么定义_箭头函数与传统函数有何不同?

JavaScript定义函数有传统函数(声明/表达式)和箭头函数两种,核心区别在于this绑定、无arguments、不可new调用、无prototype;箭头函数继承外层this,适用于回调和纯计算,不适用于对象方法或构造函数。

JavaScript 中定义函数主要有两种方式:传统函数声明/表达式和箭头函数。它们在语法、this 绑定、arguments 对象、new 调用等方面有本质区别。

怎么定义函数

传统函数可通过三种常见方式定义:

  • 函数声明:以 function 开头,有函数名,会被提升(hoisted)
    function add(a, b) { return a + b; }
  • 函数表达式:赋值给变量,可具名或匿名,不会被完全提升
    const multiply = function(a, b) { return a * b; };
  • 箭头函数:简洁语法,无函数名(匿名),不被提升,必须先声明后使用
    const power = (x, y) => x ** y;

箭头函数与传统函数的核心区别

关键差异不在“写法简不简洁”,而在于运行时行为:

  • this 绑定不同:箭头函数没有自己的 this,它继承外层词法作用域的 this;传统函数的 this 在调用时动态绑定(取决于如何调用)
  • 没有 arguments 对象:箭头函数内部访问不到 arguments,需用剩余参数 ...args 替代
  • 不能作为构造函数:箭头函数没有 prototype,调用 new 会报错;传统函数可以
  • 没有 new.target:无法检测是否被 new 调用
  • 没有原型属性(prototype):因此也不能用于需要原型链的场景(如继承)

什么时候该用箭头函数

适合用于:
– 简短的回调(如数组方法 mapfilterreduce
– 需要保持外层 this 的场景(如事件处理器、定时器中避免 bind
– 工具函数、纯计算逻辑(无状态、无 this 依赖)

不适合用于:
– 定义对象方法(容易因 this 指向错误导致问题)
– 需要 arguments 的老式写法
– 构造函数、需要 prototypenew 的场景

一个典型对比示例

假设有一个计数器对象:

const counter = {
  value: 0,
  // 传统函数:this 指向 counter
  increment: function() {
    this.value++;
    return this.value;
  },
  // 箭头函数:this 指向外层(通常是 global 或 undefined)
  // ❌ 错误用法:this.value 是 undefined
  badIncrement: () => this.value++ 
};

此时 counter.increment() 正常工作,但 counter.badIncrement() 会出错——这正是理解差异的关键所在。