ES6 函数新特性

一、ES6 函数核心新特性总览

  1. 箭头函数(最常用)
  2. 函数参数默认值
  3. rest 剩余参数
  4. 展开运算符 ...(函数调用)
  5. name 属性
  6. length 属性修正
  7. 函数参数的解构赋值
  8. 严格模式变化
  9. 尾调用优化(ES6 规范,部分引擎支持)

二、箭头函数(=>)

1. 基础语法

// 完整写法
const fn = (a, b) => { return a + b; }

// 简化写法(只有一条 return 语句)
const fn = (a, b) => a + b;

// 只有一个参数:省略括号
const fn = x => x * 2;

// 没有参数:必须写括号
const fn = () => console.log('hello');

2. 核心特性

  1. 没有自己的 this
  • 箭头函数的 this 继承自外层作用域的 this(词法作用域)
  • 不会被 call/apply/bind 改变
  1. 没有 arguments
  • rest 参数 替代
  1. 不能作为构造函数(不能 new)
  2. 没有 prototype
  3. 不能用作 Generator 函数

3. this 指向规则

const obj = {
  name: 'zs',
  say: function() {
    // 普通函数:this = obj
    setTimeout(() => {
      console.log(this.name); // zs(继承外层 this)
    });
  }
};

4. 不适用场景

  • 对象方法(会导致 this 丢失)
  • 构造函数
  • 需要动态 this 的场景(DOM 事件、原型方法)

三、函数参数默认值

1. 基础用法

function log(x, y = 'world') {
  console.log(x, y);
}
log('hello'); // hello world

2. 重要规则

  1. 参数是单独作用域
  • 参数默认值不会访问函数内部变量
  1. 默认值触发条件:严格等于 undefined
  • null 不会触发默认值
  1. 与解构赋值结合
function fetch({ url, method = 'GET' } = {}) {
  console.log(method);
}
fetch(); // GET(不传参也不报错)

4. 对 length 的影响

设置了默认值的参数,不计入 length

function fn(a, b = 1, c) {}
console.log(fn.length); // 1(只算第一个无默认值参数)

四、rest 剩余参数(...变量名)

1. 作用

接收多余的实参,变成一个真数组(替代 arguments)

2. 语法

function sum(...nums) {
  return nums.reduce((a, b) => a + b);
}
sum(1,2,3); // 6

3. 与 arguments 区别

  • rest:真数组,可直接用数组方法
  • arguments:伪数组,需要 Array.from / [...arguments]

4. 规则

  • 必须是最后一个参数
  • 一个函数只能有一个 rest 参数

五、展开运算符 ...(函数调用)

1. 作用

把数组/类数组打散成独立参数

2. 用法

const arr = [1,2,3];
console.log(...arr); // 1 2 3

Math.max(...arr); // 3

3. 常见用途

  • 替代 apply
  • 合并数组
  • 复制数组
  • 类数组转数组

六、函数的 name 属性

ES6 给函数增加了 name 属性,方便调试:

function foo() {}
foo.name; // "foo"

const bar = function() {};
bar.name; // "bar"

(new Function).name; // "anonymous"

七、函数参数解构赋值

// 对象解构
function print({ name, age }) {
  console.log(name, age);
}

// 数组解构
function sum([a, b]) {
  return a + b;
}

最佳实践:解构 + 默认值兜底

function fn({ a = 1, b = 2 } = {}) {}

八、严格模式的变化

  1. 只要参数使用了默认值、解构、rest,函数内部不能手动声明严格模式
  2. 原因:参数和函数体属于不同作用域,规则冲突

错误示例:

// 报错
function fn(a = 1) {
  'use strict';
}

九、尾调用与尾递归优化

1. 定义

函数最后一步只是调用另一个函数,无其他操作。

function f(x) {
  return g(x); // 尾调用
}

2. 优化原理

不再保存外层调用栈,只保留最后一层,防止栈溢出。

3. 支持情况

  • 严格模式下
  • 部分引擎支持(Safari,部分 Node 版本)
  • Chrome/V8 目前不支持

十、ES6 函数最佳实践

  1. 能用箭头函数就用箭头函数(回调、工具函数)
  2. 永远用 rest 替代 arguments
  3. 参数默认值 + 解构 = 最优雅传参
  4. 对象方法不要用箭头函数
  5. 函数参数尽量不多于 3 个,多用对象解构
  6. 默认值最后写,避免 length 异常

十一、面试高频题总结

  1. 箭头函数和普通函数的区别?
  2. 箭头函数的 this 指向?
  3. rest 和 arguments 区别?
  4. 参数默认值对 length 的影响?
  5. 解构参数如何设置默认值防止报错?
  6. 什么是尾调用?有什么用?

总结

ES6 函数全部核心特性、底层原理、坑点、实战规则
- 箭头函数:无this、无arguments、不能new
- 默认值:仅undefined触发、独立作用域
- rest:真数组、最后一个参数
- 展开运算符:打散数组为参数
- 最佳实践:箭头函数 + rest + 解构默认值