icon
箭头函数

箭头函数

箭头函数(Arrow Function)是 ES6 引入的简洁函数语法,使用 => 定义。

基本语法

// 传统函数
function add(a, b) {
  return a + b;
}

// 箭头函数
const add = (a, b) => {
  return a + b;
};

// 单表达式,可以省略大括号和 return
const add = (a, b) => a + b;

// 单个参数,可以省略括号
const square = x => x * x;

// 无参数,需要括号
const greet = () => 'Hello';

// 返回对象,需要用括号包裹
const createObj = () => ({ name: 'Alice' });

特点

  1. 没有 this 绑定
    • 箭头函数没有自己的 this,继承外层作用域的 this
const obj = {
  name: 'Alice',
  traditional: function() {
    console.log(this.name); // 'Alice'
  },
  arrow: () => {
    console.log(this.name); // undefined (继承外层 this)
  }
};

obj.traditional(); // 'Alice'
obj.arrow();       // undefined
  1. 不能作为构造函数
    • 箭头函数不能使用 new 调用
const Person = (name) => {
  this.name = name;
};

new Person('Alice'); // TypeError: Person is not a constructor
  1. 没有 arguments 对象
    • 箭头函数没有 arguments,可以使用剩余参数
function traditional() {
  console.log(arguments); // Arguments 对象
}

const arrow = (...args) => {
  console.log(args); // 数组
};

traditional(1, 2, 3);
arrow(1, 2, 3);
  1. 没有 prototype
    • 箭头函数没有 prototype 属性
const arrow = () => {};
console.log(arrow.prototype); // undefined

function traditional() {}
console.log(traditional.prototype); // { constructor: f }

实际应用

  1. 数组方法
const numbers = [1, 2, 3, 4, 5];

// map
const doubled = numbers.map(n => n * 2);

// filter
const evens = numbers.filter(n => n % 2 === 0);

// reduce
const sum = numbers.reduce((acc, n) => acc + n, 0);

// forEach
numbers.forEach(n => console.log(n));
  1. 回调函数
// setTimeout
setTimeout(() => {
  console.log('Delayed');
}, 1000);

// 事件处理
button.addEventListener('click', () => {
  console.log('Clicked');
});

// Promise
fetch('/api/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));
  1. 保持 this 上下文
class Counter {
  constructor() {
    this.count = 0;
  }

  // 传统函数需要绑定 this
  increment1() {
    setTimeout(function() {
      this.count++; // this 指向 window/global
    }, 1000);
  }

  // 箭头函数自动绑定
  increment2() {
    setTimeout(() => {
      this.count++; // this 指向 Counter 实例
    }, 1000);
  }
}
  1. 函数式编程
// 高阶函数
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);

const addOne = x => x + 1;
const multiplyTwo = x => x * 2;
const square = x => x * x;

const composed = compose(square, multiplyTwo, addOne);
console.log(composed(3)); // ((3 + 1) * 2) ^ 2 = 64
  1. 对象方法简写
const obj = {
  name: 'Alice',
  // 传统方法
  greet1: function() {
    return `Hello, ${this.name}`;
  },
  // 箭头函数(不推荐,this 不会指向 obj)
  greet2: () => {
    return `Hello, ${this.name}`; // this 不是 obj
  },
  // 简写方法(推荐)
  greet3() {
    return `Hello, ${this.name}`;
  }
};

何时使用箭头函数

适合使用:

  • 回调函数
  • 数组方法(map、filter、reduce 等)
  • 需要保持 this 上下文
  • 简短的函数表达式
// 适合
const numbers = [1, 2, 3];
const doubled = numbers.map(n => n * 2);

// 适合
class Component {
  handleClick = () => {
    this.setState({ clicked: true });
  };
}

不适合使用:

  • 对象方法(需要 this 指向对象)
  • 构造函数
  • 需要 arguments 对象
  • 需要动态 this
// 不适合
const obj = {
  name: 'Alice',
  getName: () => {
    return this.name; // this 不是 obj
  }
};

// 应该使用
const obj = {
  name: 'Alice',
  getName() {
    return this.name; // this 是 obj
  }
};

嵌套箭头函数

// 柯里化
const add = a => b => c => a + b + c;
console.log(add(1)(2)(3)); // 6

// 等价于
const add = function(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
};

与普通函数的区别总结

| 特性 | 箭头函数 | 普通函数 | |------|----------|----------| | this | 继承外层 | 动态绑定 | | arguments | 无 | 有 | | prototype | 无 | 有 | | 构造函数 | 不能 | 可以 | | 提升 | 不提升 | 提升(函数声明) |

注意事项

  1. this 绑定时机
const obj = {
  name: 'Alice',
  traditional: function() {
    return function() {
      return this.name; // this 是全局对象
    };
  },
  arrow: function() {
    return () => {
      return this.name; // this 是 obj
    };
  }
};

const t = obj.traditional();
const a = obj.arrow();

console.log(t()); // undefined
console.log(a()); // 'Alice'
  1. 不能改变 this
const arrow = () => {
  console.log(this);
};

arrow.call({ name: 'Alice' }); // this 不会改变
arrow.apply({ name: 'Bob' });  // this 不会改变
const bound = arrow.bind({ name: 'Charlie' });
bound(); // this 不会改变
  1. 简洁性 vs 可读性
// 简洁但可能难读
const process = data => data.map(x => x * 2).filter(x => x > 10).reduce((a, b) => a + b);

// 更清晰
const process = data => {
  const doubled = data.map(x => x * 2);
  const filtered = doubled.filter(x => x > 10);
  return filtered.reduce((a, b) => a + b);
};
  1. 调试信息
// 箭头函数没有函数名,调试时可能不方便
const func = () => {}; // 显示为 anonymous

// 可以给变量命名
const namedFunc = () => {};