作者选择了COVID-19 救济基金来接受捐赠,作为Write for DOnations计划的一部分。
介绍
在ECMAScript 2015 中,JavaScript语言引入了默认函数参数。这使开发人员能够初始化函数,如果该参数不提供给函数调用默认值。以这种方式初始化函数参数将使您的函数更易于阅读且不易出错,并将为您的函数提供默认行为。这将帮助您避免因传入参数和解构不存在的对象而导致的错误。undefined
在本文中,您将回顾参数和实参之间的区别,了解如何在函数中使用默认参数,查看支持默认参数的替代方法,并了解哪些类型的值和表达式可以用作默认参数。您还将通过示例来演示默认参数如何在 JavaScript 中工作。
参数和参数
在解释默认函数参数之前,重要的是要知道参数可以默认为什么。因此,我们将首先回顾函数中自变量和形参之间的区别。如果您想了解更多关于这种区别的信息,请查看我们之前在JavaScript 系列中的文章,如何在 JavaScript 中定义函数。
在以下代码块中,您将创建一个函数,该函数返回给定数字的立方体,定义为x
:
// Define a function to cube a number
function cube(x) {
return x * x * x
}
x
这个例子中的变量是一个参数——一个传递给函数的命名变量。参数必须始终包含在变量中,并且不得具有直接值。
现在看看下一个代码块,它调用cube
您刚刚创建的函数:
// Invoke cube function
cube(10)
这将提供以下输出:
Output1000
在这种情况下,10
是一个参数——一个在调用时传递给函数的值。通常,该值也将包含在变量中,例如在下一个示例中:
// Assign a number to a variable
const number = 10
// Invoke cube function
cube(number)
这将产生相同的结果:
Output1000
如果您不将参数传递给需要一个参数的函数,则该函数将隐式undefined
用作值:
// Invoke the cube function without passing an argument
cube()
这将返回:
OutputNaN
在这种情况下,cube()
正在尝试计算 的值undefined * undefined * undefined
,这将导致NaN
或“不是数字”。有关更多信息,请查看了解 JavaScript 中的数据类型的数字部分。
这种自动行为有时可能是一个问题。在某些情况下,即使没有参数传递给函数,您也可能希望参数具有值。这就是默认参数功能派上用场的地方,您将在下一节中介绍该主题。
默认参数语法
通过在 ES2015 中添加默认参数,您现在可以为任何参数分配默认值,该函数将使用该默认值而不是undefined
在没有参数的情况下调用。本节将首先向您展示如何手动执行此操作,然后将指导您设置默认参数。
如果没有默认参数,您必须显式检查undefined
值以设置默认值,如下例所示:
// Check for undefined manually
function cube(x) {
if (typeof x === 'undefined') {
x = 5
}
return x * x * x
}
cube()
这使用条件语句来检查值是否已自动提供为 as undefined
,然后设置x
as的值5
。这将导致以下输出:
Output125
相比之下,使用默认参数以更少的代码实现相同的目标。您可以cube
通过使用相等赋值运算符 ( =
) 为其分配参数来为参数设置默认值,如下所示:
// Define a cube function with a default value
function cube(x = 5) {
return x * x * x
}
现在,当cube
函数在没有参数的情况下被调用时,它将分配5
给x
并返回计算而不是NaN
:
// Invoke cube function without an argument
cube()
Output125
当传递参数时,它仍将按预期运行,忽略默认值:
// Invoke cube function with an argument
cube(2)
Output8
但是,需要注意的一个重要警告是,默认参数值还将覆盖undefined
作为参数传递给函数的显式传递,如下所示:
// Invoke cube function with undefined
cube(undefined)
这将使计算x
等于5
:
Output125
在这种情况下,计算了默认参数值,并且没有显式undefined
值覆盖它们。
现在您已经了解了默认参数的基本语法,下一节将展示默认参数如何处理不同的数据类型。
默认参数数据类型
任何原始值或对象都可以用作默认参数值。在本节中,您将看到这种灵活性如何增加使用默认参数的方式。
首先,使用数字、字符串、布尔值、对象、数组和空值作为默认值设置参数。此示例将使用箭头函数语法:
// Create functions with a default value for each data type
const defaultNumber = (number = 42) => console.log(number)
const defaultString = (string = 'Shark') => console.log(string)
const defaultBoolean = (boolean = true) => console.log(boolean)
const defaultObject = (object = { id: 7 }) => console.log(object)
const defaultArray = (array = [1, 2, 3]) => console.log(array)
const defaultNull = (nullValue = null) => console.log(nullValue)
当这些函数在不带参数的情况下被调用时,它们都会使用默认值:
// Invoke each function
defaultNumber()
defaultString()
defaultBoolean()
defaultObject()
defaultArray()
defaultNull()
Output42
"Shark"
true
{id: 7}
(3) [1, 2, 3]
null
请注意,每次调用函数时都会创建在默认参数中创建的任何对象。默认参数的常见用例之一是使用此行为从对象中获取值。如果您尝试从不存在的对象中解构或访问值,则会引发错误。然而,如果默认参数是一个空对象,它只会给你undefined
值而不是抛出错误:
// Define a settings function with a default object
function settings(options = {}) {
const { theme, debug } = options
// Do something with settings
}
这将避免因解构不存在的对象而导致的错误。
现在您已经了解了默认参数如何处理不同的数据类型,下一节将解释多个默认参数如何协同工作。
使用多个默认参数
您可以在函数中使用任意数量的默认参数。本节将向您展示如何执行此操作,以及如何在实际示例中使用它来操作DOM。
首先,声明一个sum()
带有多个默认参数的函数:
// Define a function to add two values
function sum(a = 1, b = 2) {
return a + b
}
sum()
这将导致以下默认计算:
Output3
此外,参数中使用的值可以用于任何后续的默认参数,从左到右。例如,这个createUser
函数创建一个用户对象userObj
作为第三个参数,函数本身所做的就是返回userObj
前两个参数:
// Define a function to create a user object using parameters
function createUser(name, rank, userObj = { name, rank }) {
return userObj
}
// Create user
const user = createUser('Jean-Luc Picard', 'Captain')
如果你打电话user
到这里,你会得到以下信息:
Output{name: "Jean-Luc Picard", rank: "Captain"}
通常建议将所有默认参数放在参数列表的末尾,以便您可以轻松地省略可选值。如果首先使用默认参数,则必须显式传递undefined
以使用默认值。
以下是列表开头带有默认参数的示例:
// Define a function with a default parameter at the start of the list
function defaultFirst(a = 1, b) {
return a + b
}
调用此函数时,您必须defaultFirst()
使用两个参数进行调用:
defaultFirst(undefined, 2)
这将给出以下内容:
Output3
这是列表末尾带有默认参数的示例:
// Define a function with a default parameter at the end of the list
function defaultLast(a, b = 1) {
return a + b
}
defaultLast(2)
这将产生相同的值:
Output3
这两个函数具有相同的结果,但具有默认值 last 的函数可以进行更清晰的函数调用。
对于实际示例,这里有一个函数,它将创建一个 DOM 元素,并添加文本标签和类(如果存在)。
// Define function to create an element
function createNewElement(tag, text, classNames = []) {
const el = document.createElement(tag)
el.textContent = text
classNames.forEach(className => {
el.classList.add(className)
})
return el
}
您可以使用数组中的某些类调用该函数:
const greeting = createNewElement('p', 'Hello!', ['greeting', 'active'])
调用greeting
将给出以下值:
Output<p class="greeting active">Hello!</p>
但是,如果您将classNames
数组排除在函数调用之外,它仍然可以工作。
const greeting2 = createNewElement('p', 'Hello!')
greeting2
现在具有以下值:
Output<p>Hello!</p>
在这个例子中,forEach()
可以毫无问题地用于空数组。如果该空数组未在默认参数中设置,则会出现以下错误:
OutputVM2673:5 Uncaught TypeError: Cannot read property 'forEach' of undefined
at createNewElement (<anonymous>:5:14)
at <anonymous>:12:18
现在您已经了解了多个默认参数是如何交互的,您可以继续下一部分以了解函数调用如何作为默认参数工作。
函数调用作为默认参数
除了基元和对象,调用函数的结果还可以用作默认参数。
在此代码块中,您将创建一个返回随机数的函数,然后将结果用作cube
函数中的默认参数值:
// Define a function to return a random number from 1 to 10
function getRandomNumber() {
return Math.floor(Math.random() * 10)
}
// Use the random number function as a default parameter for the cube function
function cube(x = getRandomNumber()) {
return x * x * x
}
现在调用cube
不带参数的函数每次调用都会有可能不同的结果:
// Invoke cube function twice for two potentially different results
cube()
cube()
这些函数调用的输出会有所不同:
Output512
64
您甚至可以使用内置方法,例如Math
对象上的方法,并将一个函数调用中返回的值用作另一个函数的参数。
在以下示例中,将随机数分配给x
,用作cube
您创建的函数中的参数。y
然后,该参数将计算数字的立方根并检查x
和y
是否相等:
// Assign a random number to x
// Assign the cube root of the result of the cube function and x to y
function doesXEqualY(x = getRandomNumber(), y = Math.cbrt(cube(x))) {
return x === y
}
doesXEqualY()
这将给出以下内容:
Outputtrue
默认参数甚至可以是函数定义,如本例所示,它将参数定义为inner
函数并返回 的函数调用parameter
:
// Define a function with a default parameter that is an anonymous function
function outer(
parameter = function inner() {
return 100
}
) {
return parameter()
}
// Invoke outer function
outer()
Output100
inner
每次outer
调用该函数时,都会从头开始创建该函数。
结论
在本文中,您了解了什么是默认函数参数以及如何使用它们。现在您可以使用默认参数来帮助保持您的函数简洁易读。您还可以预先将空对象和数组分配给参数,以在处理诸如从对象检索值或遍历数组等情况时减少复杂性和代码行数。
如果您想了解有关 JavaScript 的更多信息,请查看我们的How To Code in JavaScript 系列的主页,或浏览我们的How to Code in Node.js 系列以获取有关后端开发的文章。