← JavaScript函数参数 JavaScript变量提升 →

JavaScript默认参数

原创 2026-03-12 JavaScript 已有人查阅

JavaScript默认参数指南:从基础概念到进阶应用

理解默认参数之前:先分清参数和实参

在日常开发交流中,我经常听到同事把"参数"和"实参"混着说。虽然大多数情况下大家都能理解对方的意思,但在学习默认参数这个概念时,我们需要先厘清这两个术语的区别。

参数(Parameter):定义函数时在括号中声明的变量
实参(Argument):调用函数时实际传入的值

// a 和 b 是参数(Parameters)
function add(a, b) {
    return a + b;
}

// 5 和 3 是实参(Arguments)
add(5, 3);

这个概念区分很重要,因为默认参数本质上是在说:当某个参数的实参没有被提供时,这个参数应该用什么默认值

什么是JavaScript默认参数?

默认参数是ES6引入的特性,它允许我们在定义函数时为参数指定默认值。当函数调用时,如果某个参数没有被传入值,或者传入的是undefined,这个参数就会使用我们预先定义的默认值。

function greet(name = "访客") {
    console.log(`你好,${name}!`);
}

greet("张三");  // 你好,张三!
greet();        // 你好,访客!
greet(undefined); // 你好,访客!

默认参数的基本语法

function 函数名(参数1 = 默认值1, 参数2 = 默认值2) {
    // 函数体
}

深入理解默认参数的工作机制

1. 基础使用场景

来看一个项目开发中常见的例子:计算商品折扣后的价格

function calculatePrice(originalPrice, discount = 0, taxRate = 0.06) {
    let discountedPrice = originalPrice * (1 - discount);
    let finalPrice = discountedPrice * (1 + taxRate);
    return finalPrice.toFixed(2);
}

// 使用默认折扣和税率
console.log(calculatePrice(100));        // 106.00
// 只指定折扣,使用默认税率
console.log(calculatePrice(100, 0.1));    // 95.40
// 指定所有参数
console.log(calculatePrice(100, 0.2, 0.08)); // 86.40

2. 多个默认参数的顺序问题

默认参数的位置会影响函数的行为:

function createUser(name, age = 18, country) {
    console.log(`姓名:${name},年龄:${age},国家:${country}`);
}

createUser("李四", 20, "我国");  // 姓名:李四,年龄:20,国家:我国
createUser("王五", "我国");       // 姓名:王五,年龄:我国,国家:undefined(不符合预期)

个人经验分享:在定义函数时,建议将有默认值的参数放在参数列表的末尾。这样调用时就不用为了跳过某个参数而特意传入undefined。

// 更好的写法
function createUser(name, country, age = 18) {
    console.log(`姓名:${name},国家:${country},年龄:${age}`);
}

createUser("赵六", "我国");        // 姓名:赵六,国家:我国,年龄:18
createUser("钱七", "美国", 25);    // 姓名:钱七,国家:美国,年龄:25

3. 传入undefined vs 传入null

这是个容易混淆的地方:undefined会触发默认值,但null不会。

function test(value = "默认值") {
    console.log(value);
}

test(undefined);    // 默认值
test(null);         // null
test("");           // (空字符串)
test(0);            // 0
test(false);        // false

为什么要这么设计?
JavaScript将undefined视为"没有提供值",而null视为"提供了值,但这个值是空"。这种区分让我们可以灵活地控制是否使用默认值。

4. 默认值可以是表达式

默认值不限于字面量,它可以是任何有效的JavaScript表达式:

function getCurrentYear() {
    return new Date().getFullYear();
}

function registerUser(username, year = getCurrentYear()) {
    console.log(`用户${username}注册于${year}年`);
}

registerUser("张三");  // 用户张三注册于2026年

甚至可以是前面的参数:

function buildUrl(protocol = "https", domain, port = protocol === "https" ? 443 : 80) {
    return `${protocol}://${domain}:${port}`;
}

console.log(buildUrl("http", "example.com"));  // http://example.com:80
console.log(buildUrl("https", "example.com")); // https://example.com:443

默认参数的求值时机

一个重要特性:默认参数在每次函数调用时重新求值,而不是在函数定义时只计算一次。

function append(value, array = []) {
    array.push(value);
    return array;
}

console.log(append(1));  // [1]
console.log(append(2));  // [2],而不是[1, 2]

每次调用都会创建一个新的空数组作为默认值,不会在不同调用之间共享。

默认参数与解构赋值的结合

这是现在JavaScript中很实用的组合:

// 对象参数解构 + 默认值
function initGame({
    playerName = "玩家1",
    difficulty = "普通",
    map = "初始地图"
} = {}) {
    console.log(`开始游戏:${playerName},难度:${difficulty},地图:${map}`);
}

initGame();                                    // 全部使用默认值
initGame({ playerName: "大神", difficulty: "困难" }); // 部分指定
initGame({ map: "隐藏地图" });                   // 指定地图

// 数组参数解构 + 默认值
function parseCoordinates([x = 0, y = 0, z = 0] = []) {
    return `坐标:(${x}, ${y}, ${z})`;
}

console.log(parseCoordinates());           // 坐标:(0, 0, 0)
console.log(parseCoordinates([10, 20]));    // 坐标:(10, 20, 0)

项目开发中的使用技巧

技巧1:配置对象模式

当函数参数过多时,使用默认参数配合对象解构:

function createHttpRequest({
    method = 'GET',
    url,
    timeout = 5000,
    retries = 3,
    headers = {},
    data = null
} = {}) {
    // 参数验证
    if (!url) {
        throw new Error('URL不能为空');
    }
    
    console.log(`发起${method}请求:${url},超时${timeout}ms,重试${retries}次`);
    // 实际的请求逻辑...
}

// 调用方式清晰明了
createHttpRequest({ url: '/api/users' });
createHttpRequest({ 
    method: 'POST', 
    url: '/api/users', 
    data: { name: '李四' },
    timeout: 10000 
});

技巧2:默认参数实现函数重载

function formatDate(date = new Date(), format = 'YYYY-MM-DD') {
    // 如果没有传入date,使用当前时间
    // 如果没有指定格式,使用默认格式
    console.log(`格式化日期:${date},格式:${format}`);
}

formatDate();                    // 使用当前时间和默认格式
formatDate(new Date('2026-05-01')); // 指定日期,使用默认格式
formatDate(new Date(), 'YYYY年MM月DD日'); // 指定日期和格式

默认参数与arguments对象的关系

默认参数会影响arguments对象的行为:

function showArgs(a = 1, b = 2) {
    console.log('a:', a);
    console.log('b:', b);
    console.log('arguments长度:', arguments.length);
    console.log('arguments[0]:', arguments[0]);
    console.log('arguments[1]:', arguments[1]);
}

showArgs();           // 使用默认值,arguments长度为0
showArgs(10);         // a为10,b使用默认值,arguments长度为1
showArgs(10, 20);     // 两个都指定,arguments长度为2

课程知识要点

  1. 参数与实参的区别:参数是定义时的变量,实参是调用时传入的值

  2. 默认参数触发条件:只有参数值为undefined或省略时才触发

  3. null的特殊性:传入null不会触发默认值,会被当作有效值使用

  4. 默认值表达式:可以是任意JavaScript表达式,包括函数调用

  5. 求值时机:每次函数调用时重新计算,不共享

  6. 参数顺序建议:有默认值的参数放在参数列表末尾

  7. 解构配合使用:对象和数组解构可以配合默认参数,更加灵活

开发建议

在我参与过的项目中,合理使用默认参数确实让代码简洁了不少。但也有一些需要注意的地方:

推荐使用的场景:

  • 配置对象中的可选参数

  • 工具函数中的常用默认行为

  • 向后兼容的函数升级

谨慎使用的场景:

  • 默认值计算开销很大时(可以考虑缓存结果)

  • 依赖外部状态的默认值(可能导致不可预测的行为)

默认参数是现在JavaScript中既简单又实用的特性,掌握它能让你写出更健壮、更易读的代码。

← JavaScript函数参数 JavaScript变量提升 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号