JavaScript 默认参数
在学习JavaScript函数的过程中,默认参数是一个非常实用的特性。默认参数允许我们为函数参数指定默认值,当调用函数时如果没有提供相应参数或者参数值为undefined
,这些默认值就会生效。这个特性是ES6(ECMAScript 2015)引入的,大大简化了函数参数的处理逻辑。
为什么需要默认参数?
在ES6之前,如果我们想为函数参数提供默认值,通常需要在函数内部进行逻辑判断:
function greet(name) {
name = name || "访客";
return "你好," + name;
}
console.log(greet("小明")); // 输出: 你好,小明
console.log(greet()); // 输出: 你好,访客
这种方式虽然有效,但存在一个问题:如果传入的值是false
、0
、""
(空字符串)等在布尔上下文中会被视为假值的数据,也会使用默认值,这可能不是我们想要的结果。
默认参数语法
ES6引入的默认参数语法非常直观:
function functionName(param1 = defaultValue1, param2 = defaultValue2, ...) {
// 函数体
}
让我们看一个简单的例子:
function greet(name = "访客") {
return "你好," + name;
}
console.log(greet("小明")); // 输出: 你好,小明
console.log(greet()); // 输出: 你好,访客
console.log(greet(undefined)); // 输出: 你好,访客
备注
只有当参数值为undefined
时,默认值才会生效。其他所有值(包括null
、false
、0
、""
等)都会被视为有效值。
默认参数的高级特性
1. 表达式作为默认值
默认参数可以是表达式,这些表达式会在函数调用时被求值:
function getDate(timestamp = Date.now()) {
return new Date(timestamp);
}
console.log(getDate()); // 输出当前时间
// 等待一会儿后再调用
console.log(getDate()); // 输出新的当前时间
2. 使用前面的参数
一个参数的默认值可以引用前面定义的参数:
function calculatePrice(price, tax = price * 0.1, shipping = price >= 100 ? 0 : 10) {
return price + tax + shipping;
}
console.log(calculatePrice(100)); // 输出: 110 (100 + 10 + 0)
console.log(calculatePrice(50)); // 输出: 65 (50 + 5 + 10)
3. 函数作为默认值
你可以使用函数调用的结果作为默认值:
function getDefaultName() {
console.log("获取默认名称");
return "默认用户";
}
function greet(name = getDefaultName()) {
return "你好," + name;
}
console.log(greet("小明")); // 输出: 你好,小明
// getDefaultName()函数不会被调用
console.log(greet());
// 控制台首先输出: 获取默认名称
// 然后输出: 你好,默认用户
提示
注意:默认参数函数只会在需要时被调用。如果提供了参数值,则不会执行默认参数函数。
解构赋值与默认参数
默认参数可以与解构赋值结合使用:
function createUser({name = "用户", age = 18, isAdmin = false} = {}) {
return {
name,
age,
role: isAdmin ? "管理员" : "普通用户"
};
}
console.log(createUser());
// 输出: {name: "用户", age: 18, role: "普通用户"}
console.log(createUser({name: "小红", isAdmin: true}));
// 输出: {name: "小红", age: 18, role: "管理员"}
上面的例子中,我们使用了两层默认值:
- 参数本身默认为空对象
{} = {}
- 解构赋值内的各个属性也有默认值
默认参数与arguments对象
使用默认参数会影响arguments
对象的行为。在严格模式下,arguments
对象不会反映参数的默认值:
function test(a = 1, b = 2) {
"use strict";
console.log(arguments.length);
console.log(a, arguments[0]);
console.log(b, arguments[1]);
}
test(); // 输出: 0, 1 undefined, 2 undefined
test(10); // 输出: 1, 10 10, 2 undefined
test(10, 20); // 输出: 2, 10 10, 20 20
实际应用场景
场景1:配置对象
默认参数在处理配置对象时非常有用:
function configureApp(options = {}) {
const {
debug = false,
timeout = 1000,
maxRetries = 3,
theme = "light"
} = options;
console.log(`应用配置: debug=${debug}, timeout=${timeout}ms, maxRetries=${maxRetries}, theme=${theme}`);
// 进一步的初始化逻辑...
}
// 使用默认配置
configureApp();
// 输出: 应用配置: debug=false, timeout=1000ms, maxRetries=3, theme=light
// 覆盖部分配置
configureApp({ debug: true, theme: "dark" });
// 输出: 应用配置: debug=true, timeout=1000ms, maxRetries=3, theme=dark