了解 JavaScript 中的默认参数

作者选择了 COVID-19 救援基金作为 Write for Donations计划的一部分接受捐款。

介绍

ECMAScript 2015,在 JavaScript语言中引入了 _default 函数参数,这些参数允许开发人员以默认值初始化 函数如果参数未提供到函数调用中。以这种方式初始化函数参数将使您的函数更容易阅读,更不容易出现错误,并为您的函数提供默认行为。

在本文中,您将查看参数和参数之间的差异,了解如何在函数中使用默认参数,查看支持默认参数的替代方法,并了解哪些类型的值和表达式可以作为默认参数使用。

论点和参数

在解释默认函数参数之前,重要的是要知道参数可以默认为什么。 因此,我们将首先审查函数中的 argumentsparameters 之间的差异。

在下列代码块中,您将创建一个函数,该函数返回一个给定数的立方体,定义为x:

1// Define a function to cube a number
2function cube(x) {
3  return x * x * x
4}

此示例中的x变量是 parameter - 一个被命名变量转化为函数. 一个参数必须始终包含在变量中,而不应该有直接值。

现在来看看下一个代码块,它称呼你刚刚创建的cube函数:

1// Invoke cube function
2cube(10)

这将产生以下产出:

1[secondary_label Output]
21000

在这种情况下,‘10’是_argument_,即在调用函数时传递给函数的值. 通常,该值也会包含在变量中,如下面的示例:

1// Assign a number to a variable
2const number = 10
3
4// Invoke cube function
5cube(number)

这将产生相同的结果:

1[secondary_label Output]
21000

如果您不将参数传递给预期一个函数,该函数将默认地使用未定义作为值:

1// Invoke the cube function without passing an argument
2cube()

这将返回:

1[secondary_label Output]
2NaN

在这种情况下,cube()试图计算undefined * undefined * undefined的值,结果是NaN不是一个数字

在某些情况下,您可能希望参数具有值,即使没有参数传递到函数,这就是 default parameters 功能的方便之处,这是您将在下一节中讨论的主题。

默认参数语法

通过在 ES2015 中添加默认参数,您现在可以将默认值分配给任何参数,该函数在没有参数时使用未定义而不是无定义

如果没有默认参数,您将不得不明确检查未定义值以设置默认值,如本示例所示:

 1// Check for undefined manually
 2function cube(x) {
 3  if (typeof x === 'undefined') {
 4    x = 5
 5  }
 6
 7  return x * x * x
 8}
 9
10cube()

这使用一个 条件语句来检查该值是否被自动提供为未定义,然后将x的值设置为5

1[secondary_label Output]
2125

相比之下,使用默认参数在更少的代码中实现了相同的目标. 您可以通过将其与平等分配运算符(=)分配给 cube 中的参数设置默认值,如下所示:

1// Define a cube function with a default value
2function cube(x = 5) {
3  return x * x * x
4}

现在,当在没有参数的情况下调用cube函数时,它会将5分配给x并返回计算而不是NaN:

1// Invoke cube function without an argument
2cube()
1[secondary_label Output]
2125

当一个参数被传递时,它仍然会按预期运行,而忽略了默认值:

1// Invoke cube function with an argument
2cube(2)
1[secondary_label Output]
28

但是,要注意的一个重要警告是,默认参数值也将忽略作为参数传递给函数的明确未定义,如下所示:

1// Invoke cube function with undefined
2cube(undefined)

这将给出x等于5的计算:

1[secondary_label Output]
2125

在这种情况下,默认参数值被计算,并且一个明确的未定义值没有超过它们。

现在您已经了解了默认参数的基本语法,下一节将展示默认参数如何与不同的数据类型工作。

默认参数数据类型

任何 原始值对象都可以作为默认参数值。

首先,将参数设置为 数字, 字符串, boolean,对象, 数组和 null 值作为默认值。

1// Create functions with a default value for each data type
2const defaultNumber = (number = 42) => console.log(number)
3const defaultString = (string = 'Shark') => console.log(string)
4const defaultBoolean = (boolean = true) => console.log(boolean)
5const defaultObject = (object = { id: 7 }) => console.log(object)
6const defaultArray = (array = [1, 2, 3]) => console.log(array)
7const defaultNull = (nullValue = null) => console.log(nullValue)

当这些函数在没有参数的情况下被召唤时,它们都将使用默认值:

1// Invoke each function
2defaultNumber()
3defaultString()
4defaultBoolean()
5defaultObject()
6defaultArray()
7defaultNull()
1[secondary_label Output]
242
3"Shark"
4true
5{id: 7}
6(3) [1, 2, 3]
7null

请注意,在默认参数中创建的任何对象都会在每次调用函数时被创建。默认参数的常见用例之一是使用此行为来从对象中获取值。如果您尝试从不存在的对象中破坏或访问一个值,则会引发错误。

1// Define a settings function with a default object
2function settings(options = {}) {
3  const { theme, debug } = options
4
5  // Do something with settings
6}

这将避免破坏不存在的对象造成的错误。

现在您已经看到默认参数如何与不同的数据类型工作,下一节将解释多种默认参数如何一起工作。

使用多个默认参数

此部分将向您展示如何做到这一点,以及如何使用它来操纵 DOM在现实世界的示例中。

首先,声明具有多个默认参数的sum()函数:

1// Define a function to add two values
2function sum(a = 1, b = 2) {
3  return a + b
4}
5
6sum()

这将导致以下默认计算:

1[secondary_label Output]
23

此外,参数中使用的值可以在随后的任何默认参数中使用,从左到右,例如,这个CreateUser函数将用户对象userObj创建为第三参数,而该函数本身只会以前两个参数返回userObj:

1// Define a function to create a user object using parameters
2function createUser(name, rank, userObj = { name, rank }) {
3  return userObj
4}
5
6// Create user
7const user = createUser('Jean-Luc Picard', 'Captain')

如果你在这里拨打用户,你会得到以下信息:

1[secondary_label Output]
2{name: "Jean-Luc Picard", rank: "Captain"}

通常建议将所有默认参数放置在参数列表的末尾,以便您可以轻松排除可选值。如果您先使用默认参数,则必须明确通过未定义来使用默认值。

以下是列表一开始的默认参数的示例:

1// Define a function with a default parameter at the start of the list
2function defaultFirst(a = 1, b) {
3  return a + b
4}

在调用此函数时,您需要调用DefaultFirst()两个参数:

1defaultFirst(undefined, 2)

这将给出如下:

1[secondary_label Output]
23

以下是列表末尾的默认参数的示例:

1// Define a function with a default parameter at the end of the list
2function defaultLast(a, b = 1) {
3  return a + b
4}
5
6defaultLast(2)

这将产生相同的价值:

1[secondary_label Output]
23

两个函数都有相同的结果,但具有默认值的最后一个函数允许更清洁的函数调用。

对于一个真实的例子,这里有一个函数,将创建一个DOM元素,并添加文本标签和类,如果有的话。

 1// Define function to create an element
 2function createNewElement(tag, text, classNames = []) {
 3  const el = document.createElement(tag)
 4  el.textContent = text
 5
 6  classNames.forEach(className => {
 7    el.classList.add(className)
 8  })
 9
10  return el
11}

您可以通过数组中的某些类来调用函数:

1const greeting = createNewElement('p', 'Hello!', ['greeting', 'active'])

称呼问候会给出以下值:

1[secondary_label Output]
2<p class="greeting active">Hello!</p>

但是,如果您将classNames数组排除在函数调用中,它仍然会工作。

1const greeting2 = createNewElement('p', 'Hello!')

greeting2现在有以下值:

1[secondary_label Output]
2<p>Hello!</p>

在本示例中, [forEach()](https://andsky.com/tech/tutorials/how-to-use-array-methods-in-javascript-iteration-methods#foreach() 可以用在一个空数组中,没有问题。

1[secondary_label Output]
2VM2673:5 Uncaught TypeError: Cannot read property 'forEach' of undefined
3    at createNewElement (<anonymous>:5:14)
4    at <anonymous>:12:18

现在您已经看到多种默认参数如何相互作用,您可以转到下一节,看看函数调用如何作为默认参数工作。

函数称为默认参数

除了原始值和对象外,调用函数的结果可以作为默认参数。

在此代码块中,您将创建一个函数以返回随机数,然后将结果用作一个cube函数的默认参数值:

1// Define a function to return a random number from 1 to 10
2function getRandomNumber() {
3  return Math.floor(Math.random() * 10)
4}
5
6// Use the random number function as a default parameter for the cube function
7function cube(x = getRandomNumber()) {
8  return x * x * x
9}

现在,如果在没有参数的情况下调用cube函数,每次调用它都会有潜在不同的结果:

1// Invoke cube function twice for two potentially different results
2cube()
3cube()

这些函数调用的输出将有所不同:

1[secondary_label Output]
2512
364

您甚至可以使用嵌入式方法,例如在数学对象中的方法,并在另一个函数中使用一个函数调用中返回的值作为参数。

在下面的示例中,一个随机数被分配给x,它被用作您创建的cube函数中的参数。

1// Assign a random number to x
2// Assign the cube root of the result of the cube function and x to y
3function doesXEqualY(x = getRandomNumber(), y = Math.cbrt(cube(x))) {
4  return x === y
5}
6
7doesXEqualY()

这将给出如下:

1[secondary_label Output]
2true

默认参数甚至可以是函数定义,如本示例所示,它将参数定义为内部函数,并返回函数调用为参数:

 1// Define a function with a default parameter that is an anonymous function
 2function outer(
 3  parameter = function inner() {
 4    return 100
 5  }
 6) {
 7  return parameter()
 8}
 9
10// Invoke outer function
11outer()
1[secondary_label Output]
2100

内部函数将从头开始创建,每次召唤外部函数。

结论

在本文中,您了解了默认函数参数是什么以及如何使用它们。现在您可以使用默认参数来帮助保持函数清洁和易于读取。

如果您想了解更多关于JavaScript的信息,请参阅我们的首页 如何在JavaScript中编码系列,或浏览我们的 如何在Node.js系列中编码关于后端开发的文章。

Published At
Categories with 技术
comments powered by Disqus