函数返回值
关于函数,我们还有一个重要的概念要讨论——返回值。有些函数不返回有意义的值,而另一些则返回。理解这些值是什么,如何在代码中使用它们,以及如何使函数返回有用的值非常重要。我们将在下面介绍所有这些。
什么是返回值?
返回值正如其名——函数完成时返回的值。您已经多次遇到过返回值,尽管您可能没有明确地思考过它们。
让我们回到一个熟悉的例子(来自本系列之前的一篇文章)
const myText = "The weather is cold";
const newString = myText.replace("cold", "warm");
console.log(newString); // Should print "The weather is warm"
// the replace() string function takes a string,
// replaces one substring with another, and returns
// a new string with the replacement made
在 myText 字符串上调用了 replace() 函数,并传递了两个参数
- 要查找的子字符串 (
"cold")。 - 替换它的字符串 (
"warm")。
当函数完成(运行结束)时,它会返回一个值,这是一个进行了替换的新字符串。在上面的代码中,这个返回值的结果被保存在变量 newString 中。
如果您查看 replace() 函数的 MDN 参考页面,您会看到一个名为返回值的部分。了解和理解函数返回的值非常有用,因此我们尽可能包含这些信息。
有些函数不返回任何值。(在这些情况下,我们的参考页面将返回值列为 void 或 undefined。)例如,在我们在上一篇文章中构建的 displayMessage() 函数中,调用函数时没有返回任何特定值。它只是在屏幕上的某个位置显示一个框——仅此而已!
通常,返回值用于函数是某种计算的中间步骤。您想要得到一个最终结果,这涉及到一些需要由函数计算的值。函数计算出值后,它可以返回结果,以便将其存储在变量中;您可以在计算的下一阶段使用此变量。
如何返回值
要从自定义函数返回值,您需要使用 return 关键字。我们最近在 random-canvas-circles.html 示例中看到了它的作用。我们的 draw() 函数在 HTML <canvas> 上绘制 100 个随机圆
function draw() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
for (let i = 0; i < 100; i++) {
ctx.beginPath();
ctx.fillStyle = "rgb(255 0 0 / 50%)";
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
ctx.fill();
}
}
在每次循环迭代中,对 random() 函数进行三次调用,分别生成当前圆的 x 坐标、y 坐标和 半径的随机值。random() 函数接受一个参数——一个整数——并返回一个介于 0 和该数字之间的随机整数。它看起来像这样
function random(number) {
return Math.floor(Math.random() * number);
}
这可以写成如下形式
function random(number) {
const result = Math.floor(Math.random() * number);
return result;
}
但第一个版本编写起来更快,更简洁。
每次调用函数时,我们都会返回计算结果 Math.floor(Math.random() * number)。这个返回值出现在函数被调用的位置,然后代码继续执行。
因此,当您执行以下操作时
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
如果三次 random() 调用分别返回 500、200 和 35,则该行实际上会像这样运行
ctx.arc(500, 200, 35, 0, 2 * Math.PI);
该行上的函数调用首先运行,它们的返回值被替换为函数调用,然后该行本身才执行。
实现函数返回值
让我们尝试编写一些带有返回值的函数。
-
从 GitHub 下载 function-library.html 文件到本地。这是一个简单的 HTML 页面,包含一个文本
<input>字段和一个段落。还有一个<script>元素,其中我们已将两个 HTML 元素的引用存储在两个变量中。此页面将允许您在文本框中输入一个数字,并在下面显示与该数字相关的不同数字。 -
在现有的两行下面,向此
<script>元素添加一些有用的函数jsfunction squared(num) { return num * num; } function cubed(num) { return num * num * num; } function factorial(num) { if (num < 0) return undefined; if (num === 0) return 1; let x = num - 1; while (x > 1) { num *= x; x--; } return num; }squared()和cubed()函数相当明显——它们返回作为参数给出的数字的平方或立方。factorial()函数返回给定数字的阶乘。 -
通过在现有函数下方添加以下事件处理程序,包含一种打印有关文本输入中输入的数字信息的方法
jsinput.addEventListener("change", () => { const num = parseFloat(input.value); if (isNaN(num)) { para.textContent = "You need to enter a number!"; } else { para.textContent = `${num} squared is ${squared(num)}. `; para.textContent += `${num} cubed is ${cubed(num)}. `; para.textContent += `${num} factorial is ${factorial(num)}. `; } }); -
保存您的代码,在浏览器中加载它,然后尝试一下。
以下是上述步骤 3 中 addEventListener() 函数的一些解释
- 通过添加
change事件监听器,当文本输入上触发change事件时,此函数就会运行——也就是说,当在文本input中输入新值并提交时(输入一个值,然后通过按 Tab 或 Return 使输入失去焦点)。当这个匿名函数运行时,input中的值存储在num常量中。 - 如果输入的值不是数字,
if语句会打印一条错误消息。条件检查表达式isNaN(num)是否返回true。isNaN()函数测试num值是否不是数字——如果是,它返回true,如果不是,它返回false。 - 如果条件返回
false,则num值是一个数字,并且该函数在段落元素内打印一句话,说明该数字的平方、立方和阶乘值。该语句调用squared()、cubed()和factorial()函数来计算所需的值。
注意:如果您在使示例工作时遇到问题,请将您的代码与 GitHub 上的完成版本进行比较(也可以查看其运行情况)。
添加一些您自己的函数!
此时,我们希望您尝试自己编写几个函数并将它们添加到库中。数字的平方根或立方根怎么样?或者给定半径的圆的周长?
一些额外的函数相关技巧
- 查看另一个在函数中编写错误处理的示例。通常,最好检查所有必要的参数是否已验证,并且所有可选参数都提供了某种默认值。这样,您的程序就不太可能抛出错误。
- 思考创建函数库的想法。随着您在编程生涯中走得更远,您将开始一遍又一遍地做相同类型的事情。创建您自己的实用函数库来做这些事情是一个好主意。您可以将它们复制到新代码中,甚至可以根据需要将它们应用于 HTML 页面。
总结
所以就这样——函数很有趣,非常有用,尽管关于它们的语法和功能有很多话要说,但它们相当易懂。
在下一篇文章中,我们将为您提供一些测试,您可以使用这些测试来检查您对我们在前几篇文章中提供的所有函数信息的理解和记忆程度。
另见
- 深入了解函数——一本详细的指南,涵盖更高级的函数相关信息。
- JavaScript 中的回调函数——一个常见的 JavaScript 模式是将一个函数作为参数传递给另一个函数。然后它在第一个函数内部被调用。这有点超出本课程的范围,但值得在不久的将来学习。