参数默认值就是函数没传参时用默认值,不用再自己判断 undefined。
核心两个:
① function fn(a=10)——没传 a 就是 10
② 默认值只在 undefined 时生效
坑:传 null 不会用默认值、默认参数可以用其他参数计算、默认参数放最后。
以前默认值要在函数体里写一行 if 判断,现在直接写在参数括号里,像菜单上印好。
// 以前:函数里手动判断"客人给没给"
// 收三个参数
function add(a, b, c) {
// 没给就补上 10
if (c === undefined) c = 10;
// 三个数相加
return a + b + c;
}
// 13(c 没给,用了 10)
console.log(add(1, 2));
// 现在:直接写在参数 = 后面,菜单印好默认值
// c 没传就自动是 10(写在括号里)
function add(a, b, c = 10) {
// 不用再手写 if
return a + b + c;
}
// 13(c 自动用 10)
console.log(add(1, 2));
// 6(传了 3,就用 3)
console.log(add(1, 2, 3));
|| 是个"心软"的服务员:只要客人给的是 0、空串、false,它都当成"没点",硬塞默认值。而参数默认值只认 undefined。
// || 的坑:0、""、false 都是"假值",会被误换成默认值
// 普通函数
function f(a, b) {
// 只要 b 是假值就换成 10
b = b || 10;
// 把 b 返回
return b;
}
// 10(客人明明点了 0,被当成没点!)
console.log(f(1, 0));
// 参数默认值:只在 undefined 时才兜底
// 默认值写括号里,只认 undefined
function f(a, b = 10) {
// 直接返回 b
return b;
}
// 0(0 是客人真点的,保留)
console.log(f(1, 0));
// 10(只有 undefined 才触发默认)
console.log(f(1, undefined));
如果你以前用 b = b || 10 写兜底,业务里用户传 0 表示"不限制",结果被悄悄换成 10。这种 bug 特别隐蔽——所以参数默认值最大的价值就是:0、""、false 这种"有效但假"的值不会被误伤。
实战里函数经常收一个"配置对象",这时候解构 + 默认值是最稳的组合。
// 以前:进去还得 obj.name 一个个判断
// 收一个对象
function fn(obj) {
// 没名字就写未知
let name = obj.name || "未知";
// 打印出来
console.log(name);
// 现在:参数直接解构,每个属性都能带默认值
}
// 把对象拆成 name
function fn({ name = "未知" } = {}) {
// ^^^^^^^^ 整个参数都没传时,给个空对象兜底
// 直接用拆出来的 name
console.log(name);
}
// 未知(空对象里没 name)
fn({});
// 大喇叭(传了就用传的)
fn({ name: "大喇叭" });
// 未知(连对象都没传,= {} 救了它)
fn();
注意 { name = "未知" } = {} 有两层兜底:= {} 是"客人连盘子都没端来时,自己塞个空盘子",name = "未知" 是"盘子里没这道菜时上默认"。两层各管各的,少写任何一层,调用 fn 都会报错。
① 可能在什么地方用:封装可配置的工具函数(如 ajax(url, method = "GET"))、分页函数 getPage(page = 1, size = 10)、组件默认参数、解析接口返回时兜底字段。
② 常见的问题:用 || 导致 0、"" 被覆盖;默认参数写在非最后位置调用时对不上;解构整个对象时漏写 = {},调用不传对象直接报"Cannot destructure property"。
③ 解决思路:要兜底就用参数默认值或 ??,别用 ||;有默认值的参数尽量放最后;解构对象参数一律写成 function fn({ x = 1 } = {}) 双兜底。
| API | 作用 | 参数 | 返回值 | 代码示例 |
|---|---|---|---|---|
| function f(b = 10) | 没传参、或传 undefined 时才上默认值 | 形参 = 默认值 | 一个函数 | function f(b = 10) {} |