想成功,先发疯!🤣 今天继续学习了阮一峰《ECMAScript 6入门》对函数参数默认值的详解,光看的话学的还是有点困难,必须将文档和ai相结合,现在有了ai大模型学习效率直接翻倍,因此想着写一篇文章总结一下。话不多说,直接上干货。
1. 基础用法
当调用函数时,如果某个参数未传递或显式传递 undefined
,则使用默认值。
scss
function greet(name = "Guest") {
console.log(`Hello, ${name}!`);
}
greet(); // 输出 "Hello, Guest!"
greet("Alice"); // 输出 "Hello, Alice!"
greet(undefined); // 输出 "Hello, Guest!"(显式传递 undefined)
2. 默认参数与传统方法的区别
-
传统方法 (如
||
运算符):scssfunction add(a, b) { b = b || 0; // 当 b 为 0、空字符串、null 时也会触发默认值 return a + b; } add(1); // 正确:1 + 0 = 1 add(1, 0); // 错误:0 会被替换为默认值 0(不影响结果) add(1, null); // 错误:null 会被替换为默认值 0
-
默认参数:
sqlfunction add(a, b = 0) { return a + b; } add(1, null); // 正确:null 不是 undefined,结果为 1 + null = NaN
结论 :默认参数仅在参数为
undefined
时生效,更精确可靠。
3. 参数顺序与依赖关系
-
后面的参数可以引用前面的参数:
cssfunction calculate(a, b = a) { return a + b; } calculate(2); // 2 + 2 = 4
-
前面的参数不能引用后面的参数:
cssfunction calculate(a = b, b) { // 报错:b 未定义 return a + b; }
4. 默认参数的作用域
默认参数的作用域是函数作用域,而非全局作用域。
ini
let x = 1;
function fn(y = x) { // 函数作用域内的 x 是外部的 x
let x = 2; // 函数内部的 x 会覆盖外部的 x
console.log(y); // 输出 1(默认参数初始化时使用的是外部的 x)
}
fn(); // 1
5. 默认参数与解构赋值
5.1 对象解构默认值
当函数参数是对象时,可通过解构为属性设置默认值。解构默认值仅在属性为 undefined
时生效。
示例 1:完整解构默认值
scss
function printUser({ name = "Guest", age = 0 } = {}) {
console.log(name, age);
}
printUser(); // Guest 0(未传递参数时,使用参数默认值 {},然后解构属性默认值)
printUser({ name: "Alice" }); // Alice 0(age 未传递,使用解构默认值 0)
printUser({ name: "Bob", age: 25 }); // Bob 25
printUser(undefined); // Guest 0(参数为 undefined,使用参数默认值 {})
printUser({}); // Guest 0(参数为空对象,name 和 age 均为 undefined)
示例 2:部分属性默认值
scss
function printUser({ name, age = 18 } = { name: "Unknown" }) {
console.log(name, age);
}
printUser(); // Unknown 18(参数默认值 { name: "Unknown" },age 未传递,使用解构默认值 18)
printUser({ name: "Alice" }); // Alice 18(age 未传递)
printUser({ name: "Bob", age: 30 }); // Bob 30
printUser({ age: 25 }); // Unknown 25(name 未传递,使用参数默认值 "Unknown")
关键细节:
- 参数默认值
{ name: "Unknown" }
是函数参数的默认值,当参数为undefined
或未传递时触发。 - 解构默认值
age = 18
是属性级默认值,仅在属性为undefined
时生效。
5.2 数组解构默认值
数组解构默认值用于处理参数为数组时的索引缺失问题。
示例 1:基础用法
scss
function sum([a = 0, b = 0] = [1, 2]) {
return a + b;
}
sum(); // 1 + 2 = 3(参数默认值为 [1, 2],未传递参数时使用)
sum([3]); // 3 + 0 = 3(b 未传递,使用解构默认值 0)
sum([4, 5]); // 9
sum(undefined); // 1 + 2 = 3(参数为 undefined,使用参数默认值)
sum([]); // 0 + 0 = 0(参数为空数组,a 和 b 均为 undefined)
示例 2:动态默认值
css
function sum([a = Math.random() * 10 | 0, b = a * 2] = []) {
return a + b;
}
sum(); // 生成随机数 a,b = a*2,返回 a + b
sum([5]); // 5 + 10 = 15(b 未传递,使用解构默认值 5*2)
关键细节:
- 参数默认值
[]
是函数参数的默认值,当参数为undefined
或未传递时触发。 - 解构默认值
a = 0
和b = 0
是索引级默认值,仅在对应位置为undefined
时生效。
5.3 解构默认值与参数默认值的优先级
-
参数默认值 (函数参数层面)优先级更高:当参数为
undefined
时,直接使用参数默认值。 -
解构默认值(属性 / 索引层面)仅在解构过程中处理属性 / 索引的缺失。
示例:
php
function fn({ x } = { x: 10 }) {
return x;
}
fn(undefined); // 10(参数默认值 { x: 10 } 生效)
fn({}); // undefined(参数为 {},解构 x 时无值,返回 undefined)
fn({ x: 20 }); // 20
5.4 常见错误与陷阱
-
忘记设置参数默认值:
javascriptfunction fn({ name } = {}) { // 参数默认值为 {},解构 name 时若无值则为 undefined console.log(name); } fn(undefined); // undefined(参数默认值 {} 生效,但 name 未传递)
-
解构默认值与参数默认值冲突:
phpfunction fn({ a = 1 } = { a: 2 }) { return a; } fn(); // 2(参数默认值 { a: 2 } 生效,解构默认值 a = 1 未触发) fn(undefined); // 2(同上) fn({}); // 1(参数为空对象,解构默认值 a = 1 生效)
6. 默认参数与严格模式
默认参数在严格模式下无特殊限制,但需注意其他严格模式规则(如禁止重复参数名)。
javascript
"use strict";
function fn(a, a = 1) { // 报错:重复参数名 a
return a;
}
7. 默认参数与 arguments
对象
在 ES6 中,arguments
对象不再与参数绑定,修改参数不会影响 arguments
。
ini
function fn(a = 1) {
a = 2;
console.log(arguments[0]); // 1(默认参数未被修改)
}
fn(); // 1
8. 性能注意事项
-
默认参数的计算:默认值在函数调用时计算,而非定义时。
inilet count = 0; function increment(a = count++) { return a; } increment(); // 0 increment(); // 1(count 递增)
-
避免复杂默认值:默认值应保持简单,避免高计算量操作(如函数调用、对象创建)。
9. 类方法中的默认参数
类的方法也可使用默认参数:
javascript
class Greeter {
greet(name = "Guest") {
console.log(`Hello, ${name}!`);
}
}
const g = new Greeter();
g.greet(); // Hello, Guest!
总结
默认参数是 JavaScript 中处理可选参数的优雅方式,需注意其作用域、参数顺序、与解构的结合使用等细节。合理运用默认参数可提升代码的简洁性和健壮性。