在 JavaScript 中,定义函数时通常需要给出参数列表,在调用函数时需要传入这些参数。在某些情况下,我们希望函数能够有一些默认参数,如果调用时没有传入这些参数,函数默认使用这些参数值。ES6 中引入了函数默认参数的特性,而 ES7 进一步改进了它,本文将详细介绍 ES7 函数默认参数的使用和示例。
基本语法
ES7 函数默认参数的基本语法如下:
function fn(param1 = defaultValue1, param2 = defaultValue2, ...) { // 函数体 }
在函数定义时,我们可以为函数的参数设定默认值。如果在函数调用时不给出这些参数的值,函数将采用默认值作为其参数。
例如:
function log(message = 'Hello, World!') { console.log(message); } log(); // 输出:Hello, World! log('Welcome to the world of JavaScript.'); // 输出:Welcome to the world of JavaScript.
参数默认值的规则
ES7 函数默认参数遵循以下规则:
- 如果参数默认值被设定为
undefined
,那么这个默认值表达式将会被求值; - 如果函数传递了参数,则使用传递的值而不是默认值;
- 如果函数没有传递参数,则使用默认值。
例如:
let x = 42; function foo(a = 2, b = a + x) { console.log(a, b); } foo(); // 输出:2 44 foo(3); // 输出:3 45 foo(3, 6); // 输出:3 6
在上面的例子中,变量 x
的值为 42
。我们定义了函数 foo
,其中有两个参数 a
和 b
。如果调用函数时不传入任何参数,则参数 a
的默认值为 2
,参数 b
的默认值为 a + x
,即 44
。如果传入参数 3
,则参数 a
的值为 3
,参数 b
的值为 a + x
,即 45
。如果传入参数 3
和 6
,则参数 a
的值为 3
,参数 b
的值为 6
。
与解构赋值一同使用
ES7 函数默认参数与解构赋值结合使用时能够进行更多的变化。例如:
function print({ message = 'Hello, World!', count = 1 }) { for (let i = 0; i < count; i++) { console.log(message); } } print({}); // 输出:Hello, World! print({ count: 3 }); // 输出:Hello, World! Hello, World! Hello, World! print({ message: 'Hi!', count: 2 }); // 输出:Hi! Hi!
在上面的例子中,我们定义了函数 print
,并给定了一个对象作为参数。该对象定义了两个属性 message
和 count
,并且这两个属性都有默认值。函数 print
会输出 count
次给定的 message
,如果 message
和 count
未被指定,则默认输出一次 "Hello, World!"。
此外,参数默认值还可以与数组解构一起使用,例如:
function greet([firstName = 'John', lastName = 'Doe']) { console.log(`Hello, ${firstName} ${lastName}!`); } greet([]); // 输出:Hello, John Doe! greet(['Alice']); // 输出:Hello, Alice Doe! greet(['Alice', 'Smith']); // 输出:Hello, Alice Smith!
在上面的例子中,我们定义了函数 greet
,它接收一个数组,并从中解构出两个元素 firstName
和 lastName
。如果 firstName
或 lastName
未被指定,则使用默认值 "John" 或 "Doe"。
延迟求值
利用参数默认值的特性,我们可以实现一些比较有意思的特效。例如:
function ajax(url, data = { timeout: 2000, async: true }) { // 函数体 }
在上面的代码中,当没有传入 data
参数时,我们新建了一个对象进行赋值,并将其作为默认值。这种方式看起来十分简单和方便,但是如果我们多次调用 ajax
函数,每次都需要新建一个对象,这将会浪费很多资源。
为了避免这种浪费,我们可以改变代码结构,将默认值分离出去:
function ajax(url, data) { data = Object.assign({ timeout: 2000, async: true }, data); // 函数体 }
在上面的代码中,我们先判断 data
是否传入。如果没有传入 data
,则新建一个对象并赋值。如果传入了 data
,则将传入的值与默认值进行合并,并重新赋值给 data
。
总结
ES7 函数默认参数是一种方便而实用的特性,能够大大简化我们的代码。使用参数默认值的时候需要注意量和延迟求值等特性。此外,参数默认值还可以与解构赋值等特性结合使用,获得更加灵活和丰富的功能。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a0ea4fadd4f0e0ff918a2c