ES6 函数默认值 和 剩余参数 + 箭头函数

100 阅读3分钟

ES5以及之前的参数默认值

缺点:

1. 写起来很麻烦,并且代码的阅读性是比较差的
2. 这种写法有bug

如果你输入的值被隐式的转化为false,foo函数中会使用默认参数,我们可能就想使用那些隐式转换的值,就造成了麻烦

function foo(m, n) {
  m = m || 'aaa'
  n = n || 'bbb'
  console.log(m, n)
}

//'', 0, NaN, null, undefined

foo('', 'a')
foo(0, 1)
foo(NaN, 'why')
foo(null, 'why')
foo(undefined, 'why')

ES6 的默认值

function foo(m = 'aaa', n = 'bbb'){
  console.log(m, n)
}
foo('', 'a')
foo(0, 1)
foo(NaN, 'why')
foo(null, 'why')
foo(undefined, 'why')

Snipaste_2025-04-17_19-18-34.png

可以看到除了值为undefined的使用了默认值,其他的都使用了自身的值。第一个为空的字符串,不代表不存在

默认值也可以是表达式或函数
function getDefaultName() {
  return "Anonymous";
}

function showName(name = getDefaultName()) {
  console.log(`Name: ${name}`);
}

showName(); // Name: Anonymous
showName('why') //Name: why
配合解构使用
function printInfo1({name, age} = {name: 'why', age: 18}){
  console.log(name,age)
}
printInfo1({name: 'kobe', age: 40}) //kobe 40

function printInfo2({name = 'why', age = 18} = {}){
  console.log(name,age)
}
printInfo2()//why 18
函数默认值加在哪里?解构内有默认值?
printInfo1整个参数对象默认值
printInfo2参数是空对象的默认值 {}✅ 每个属性有默认值

场景printInfo1printInfo2
默认值位置整个对象参数的默认值解构属性各自有默认值
能否省略传参?✅ 可以(如果函数写了整体默认值)✅ 可以(参数为 undefined 会变成 {})
适合什么场景?有完整对象时给整个默认参数可能是部分字段、不传字段时更灵活
函数默认值对函数的length属性的影响
function foo(x, y, z, m) {
  console.log(x, y, z, m);
}
console.log(foo.length) //4
function foo(x, y, z = 1, m) {
  console.log(x, y, z, m);
}
console.log(foo.length) //2

函数中length属性,对默认参数,以及默认参数后面的参数一律都不计算在内。 如果函数第一个参数为默认值参数,则length为0

剩余参数


一、arguments 是什么?

  • 是函数内部的一个类数组对象
  • 包含了传入函数的所有参数
  • 在普通函数中默认存在
  • 不能在箭头函数中使用!
function demo1(a, b) {
  console.log(arguments); // [Arguments] { '0': 1, '1': 2, '2': 3 }
}
demo1(1, 2, 3);

🟢 二、rest parameter 是什么?

  • 是 ES6 引入的新语法
  • 用语法 ...args 来表示剩余参数(是一个真正的数组)
  • 只能放在参数列表的最后一个位置
function demo2(...args) {
  console.log(args); // [1, 2, 3]
}
demo2(1, 2, 3);

三、两者区别总结表

特性argumentsrest parameter (...args)
是否为数组❌ 类数组对象✅ 真正的数组
支持哪些函数✅ 普通函数(function)✅ 普通函数 & 箭头函数
使用方式是否明确❌ 拿所有参数,无名字✅ 有名字,且更灵活
是否推荐❌ 不推荐(已过时)✅ 推荐(现代写法)

举个完整对比的例子:

function showArgs1(a, b) {
  console.log(arguments[0]); // 1
  console.log(arguments.length); // 3
}
showArgs1(1, 2, 3);

function showArgs2(...args) {
  console.log(args[0]); // 1
  console.log(args.length); // 3
}
showArgs2(1, 2, 3);

arguments 不适用于箭头函数

const demo = () => {
  console.log(arguments); // ❌ 报错 ReferenceError: arguments is not defined
}

最佳实践(现代 JS 推荐用法)

function sum(...nums) {
  return nums.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3, 4)); // 输出 10

拓展:rest 参数配合解构

const [first, ...rest] = [1, 2, 3, 4];
console.log(first); // 1
console.log(rest);  // [2, 3, 4]

arguments 是旧时代的产物,功能强但不方便;而 rest parameter 是更现代、更灵活、更强大的写法,推荐你优先使用 rest 参数。而出现rest参数就是希望替代arguments的


箭头函数

特性描述
✅ 更简洁的写法少了 functionreturn
✅ 自动绑定 this不会改变 this 指向(继承外层作用域)
❌ 没有 arguments要用 rest 参数 ...args 替代
❌ 不能用作构造函数箭头函数不能用 new 调用
❌ 没有 supernew.target在类中也不能用箭头函数作为方法

补充:箭头函数的thisarguments属性自身没有,会去上层作用域找

详细学习this