JavaScript 默认参数
摘要:在本教程中,您将学习如何在 ES6 中处理 JavaScript 的默认参数。
TL;DR(简要概览)
| 1 2 3 4 5 6 7 | function say(message = 'Hi') {     console.log(message); } say(); // 'Hi' say('Hello'); // 'Hello' | 
在上述代码中,say() 函数的 message 参数默认值为 'Hi'。
在 JavaScript 中,默认函数参数允许您在未传递值或传递 undefined 时,为命名参数初始化默认值。
参数与实参
有时,您可以互换使用“参数”和“实参”这两个术语。然而,严格来说,参数是您在函数声明中指定的,而实参是您传递给函数的值。
考虑以下 add() 函数:
| 1 2 3 4 5 6 | function add(x, y) {    return x + y; } add(100, 200); | 
在此示例中,x 和 y 是 add() 函数的参数,而传递给 add() 函数的值 100 和 200 是实参。
为函数设置 JavaScript 默认参数
在 JavaScript 中,参数的默认值是 undefined。这意味着,如果您未将实参传递给函数,其参数将具有 undefined 的默认值。
请参阅以下示例:
| 1 2 3 4 5 6 | function say(message) {     console.log(message); } say(); // undefined | 
say() 函数接受 message 参数。由于我们未向 say() 函数传递任何实参,因此 message 参数的值为 undefined。
假设您希望为 message 参数提供默认值 'Hi'。
一种典型的方法是测试参数值,如果其为 undefined,则使用三元运算符分配默认值:
| 1 2 3 4 5 6 7 | function say(message) {     message = typeof message !== 'undefined' ? message : 'Hi';     console.log(message); } say(); // 'Hi' | 
在此示例中,我们未向 say() 函数传递任何值。因此,message 参数的默认值为 undefined。在函数内部,我们将 message 变量重新赋值为字符串 'Hi'。
ES6 提供了一种更简单的方法来设置函数参数的默认值,如下所示:
| 1 2 3 4 5 6 7 8 | function say(message = 'Hi') {     console.log(message); } say(); // 'Hi' say(undefined); // 'Hi' say('Hello'); // 'Hello' | 
工作原理:
- 在第一次函数调用中,我们未向 say()函数传递任何实参,因此message参数采用默认值'Hi'。
- 在第二次函数调用中,我们向 say()函数传递了undefined,因此message参数也采用默认值'Hi'。
- 在第三次函数调用中,我们向 say()函数传递了字符串'Hello',因此message参数采用字符串'Hello'作为默认值。
更多 JavaScript 默认参数示例
让我们看一些更多的示例,以了解设置函数参数默认值的可用选项。
1) 传递 undefined 实参
以下 createDiv() 函数在文档中创建一个具有特定高度、宽度和边框样式的新 <div> 元素:
| 1 2 3 4 5 6 7 8 9 | function createDiv(height = '100px', width = '100px', border = 'solid 1px red') {     let div = document.createElement('div');     div.style.height = height;     div.style.width = width;     div.style.border = border;     document.body.appendChild(div);     return div; } | 
以下调用未向函数传递任何实参,因此 createDiv() 函数使用参数的默认值:
| 1 2 | createDiv(); | 
假设您希望为高度和宽度参数使用默认值,并指定边框样式。在这种情况下,您需要向前两个参数传递 undefined 值,如下所示:
| 1 2 | createDiv(undefined, undefined, 'solid 5px blue'); | 
2) 评估默认参数
JavaScript 引擎在调用函数时评估默认实参。请参阅以下示例:
| 1 2 3 4 5 6 7 8 9 | function put(toy, toyBox = []) {     toyBox.push(toy);     return toyBox; } console.log(put('Toy Car')); // -> ['Toy Car'] console.log(put('Teddy Bear')); // -> ['Teddy Bear'], not ['Toy Car','Teddy Bear'] | 
该参数可以采用函数结果作为默认值。
在此示例中,toyBox 参数的默认值是一个新数组 []。每次调用 put() 函数时,都会创建一个新的数组,因此每次调用的结果是独立的。
请看以下示例:
| 1 2 3 4 5 6 7 | function date(d = today()) {     console.log(d); } function today() {     return (new Date()).toLocaleDateString("en-US"); } date(); | 
date() 函数接受一个参数,其默认值为 today() 函数的返回值。today() 函数以指定的字符串格式返回今天的日期。
当我们声明 date() 函数时,today() 函数尚未执行,直到我们调用 date() 函数时才会被求值。
我们可以利用这一特性使参数变为强制性的。如果调用者未传入任何参数,我们可以如下抛出错误:
| 1 2 3 4 5 6 7 8 9 | function requiredArg() {    throw new Error('The argument is required'); } function add(x = requiredArg(), y = requiredArg()){    return x + y; } add(10); // error add(10,20); // OK | 
3) 在默认值中使用其他参数
你可以为参数指定一个默认值,该默认值可以引用其他默认参数,如下例所示:
| 1 2 3 4 5 6 | function add(x = 1, y = x, z = x + y) {     return x + y + z; } console.log(add()); // 4 | 
在 add() 函数中:
- x的默认值为- 1。
- y的默认值为- x,即- 1。
- z的默认值为- x + y,即- 1 + 1 = 2。
因此,add() 返回 1 + 1 + 2 = 4。
参数列表似乎具有自己的作用域。如果引用尚未初始化的参数,将会报错。例如:
| 1 2 3 4 | function subtract( x = y, y = 1 ) {     return x - y; } subtract(10); | 
错误信息:
Uncaught ReferenceError: Cannot access 'y' before initialization
4) 使用函数作为默认值
您可以使用函数的返回值作为参数的默认值。例如:
| 1 2 3 4 5 6 7 8 9 | let taxRate = () => 0.1; let getPrice = function(price, tax = price * taxRate()) {     return price + tax; }; let fullPrice = getPrice(100); console.log(fullPrice); // 110 | 
在 getPrice() 函数中,我们调用 taxRate() 函数以获取税率,并使用该税率从价格中计算税额。
5) 参数(arguments) 对象
函数内部的 arguments 对象的值是您传递给函数的实际实参的数量。例如:
| 1 2 3 4 5 6 7 8 9 | function add(x, y = 1, z = 2) {     console.log(arguments.length);     return x + y + z; } add(10); // 1 add(10, 20); // 2 add(10, 20, 30); // 3 | 
在此示例中,arguments.length 返回传递给函数的实参数量。
总结:
- 默认值设置方式简洁:通过 参数 = 默认值的形式,您可以为函数参数指定默认值。
- 仅在未传值或传 undefined时使用默认值:传null或其他值不会触发默认值。
- 默认值可以是表达式或函数调用:默认值不局限于常量,也可以是基于其他参数的计算结果或函数返回值。
- 默认参数从左到右依次解析:后面的默认参数可以依赖前面的参数值。
- arguments对象不受默认值影响:它只反映调用时实际传入的参数数量。
- 避免副作用的共享默认值:如数组或对象作为默认值时,应确保每次调用创建新实例,避免数据共享带来的副作用。
以下是 JavaScript 默认参数 的关键知识点整理成的表格,便于查阅和理解:
| 序号 | 特性 | 说明 | 示例代码片段 | 
|---|---|---|---|
| 1 | 设置默认值的语法 | 使用 参数 = 默认值的形式为函数参数设置默认值。 | function fn(x = 1) {} | 
| 2 | 触发默认值的条件 | 当参数 未传 或传入 undefined时,默认值才会生效。 | fn(); fn(undefined); | 
| 3 | 非 undefined不触发默认 | 传入 null、0、''等都视为有效值,不会触发默认值。 | fn(null);不触发默认值 | 
| 4 | 默认值可为表达式 | 默认值可以是计算表达式,甚至可以依赖前面的参数。 | function add(x = 1, y = x + 1) {} | 
| 5 | 默认值可为函数调用 | 默认值可以调用函数动态生成。 | function fn(x = getDefault()) {} | 
| 6 | 每次调用默认值重新计算 | 每次函数调用都会独立计算默认值(例如:默认值为 []会生成不同数组)。 | function fn(x = []) {} | 
| 7 | 默认值参数的顺序依赖 | 默认值参数从左到右解析,后面的参数可引用前面的参数,但反过来不行。 | function f(x = 1, y = x + 1) {} | 
| 8 | arguments不包含默认值 | 函数内部的 arguments.length只计算实际传入的参数数量,与默认值无关。 | fn(1); arguments.length === 1 | 
| 9 | 不能覆盖原始引用 | 如果默认值是引用类型(如数组、对象),注意每次调用应返回新对象,避免共享。 | function f(x = {}) {} | 
| 10 | 与旧方法的对比 | ES6 之前需使用 typeof x === 'undefined' ? default : x手动处理默认值。 | x = typeof x !== 'undefined' ? x : 1; | 
 
