函数返回值

函数返回值是本章中最后一个基础概念。有些函数在执行完毕后不会返回一个有用的值,但有些会,重要的是理解返回的是什么,怎样在你的代码中使用这些值,我们将在下面讨论这些。

前提:

了解 HTMLCSS 基础,熟悉上一课所介绍的 JavaScript 函数基础。

学习成果:
  • 什么是返回值。
  • 如何在已有函数中使用返回值。
  • 在自己的函数中加入返回值。

什么是返回值?

返回值意如其名,是指函数执行完毕后返回的值。你已经多次遇见过返回值,尽管你可能没有明确的考虑过他们。

让我们回顾一个熟悉的例子(来自本系列之前的一篇文章):

js
const myText = "天气很冷";
const newString = myText.replace("冷", "热");
console.log(newString); // 应输出“天气很热”
// replace() 字符串函数接受源字符串和目标字符串,
// 将源字符串替换为目标字符串,并返回新形成的字符串

我们对 myText 字符串调用 replace() 函数,并接收两个参数:

  • 要查找的子字符串("冷")。
  • 用于替换的字符串("热")。

当这个函数完成(完成运行)后,它返回一个值,这个值是一个新的字符串,它具有替换的功能。在上面的代码中,我们保存这个返回值,以作为 newString 变量的内容。

如果你查看 MDN 文档中 replace() 函数的页面,你会看到叫做返回值的章节。理解函数的返回值非常关键,因此我们尽可能在文档中提供此类信息。

一些函数不返回任何值(在我们的参考页中,这类函数的返回值在文档中标记为空值 void 或未定义值 undefined)。例如,前一篇文章中编写的 displayMessage() 函数在被调用时不会返回特定值,它仅负责在屏幕上显示一个弹窗。

一般来说,返回值用于函数作为计算的中间步骤。假设你需要得到一个最终结果,而该结果依赖于某些需要通过函数计算的值。函数计算完成后,可以通过返回值将结果存储在变量中,供后续计算使用。

在自定义的函数中使用返回值

要从自定义函数返回值,你需要使用 return 关键字。我们最近在 random-canvas-circles.html 示例中见过此用法。我们的 draw() 会在 HTML <canvas> 元素上随机绘制 100 个圆圈:

js
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 到该参数的随机整数:

js
function randomNumber(number) {
  return Math.floor(Math.random() * number);
}

这个函数也可以写成这样:

js
function randomNumber(number) {
  const result = Math.floor(Math.random() * number);
  return result;
}

但是第一个版本写起来更快,而且更简洁。

我们每次调用函数都返回 Math.floor(Math.random() * number) 的计算结果。该返回值会直接出现在函数被调用的位置,代码随后继续执行后续逻辑。

例如,当执行以下代码时:

js
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);

假设三次 random() 调用分别返回 50020035,则这行代码实际等价于:

js
ctx.arc(500, 200, 35, 0, 2 * Math.PI);

首先运行该行的函数调用,并将其返回值替换为函数调用,然后再执行该行本身。

主动学习:我们自己的返回值函数

让我们着手编写具有我们自己的返回值的函数。

  1. 首先,从 GitHub 的 function-library.html 文件复制一份本地副本。这个简单的 HTML 页面包含一个 <input> 文本框和一个段落。还有一个 <script> 元素,我们在其中用两个变量预存了对两个 HTML 元素的引用。这个页面允许你在文本框中输入一个数字,并在下方显示与该数字相关的不同数字。

  2. script 元素中已有的两行代码下方,插入这三个函数:

    js
    function squared(num) {
      return num * num;
    }
    
    function cubed(num) {
      return num * num * num;
    }
    
    function factorial(num) {
      var x = num;
      while (x > 1) {
        num *= x - 1;
        x--;
      }
      return num;
    }
    

    squared()cubed() 函数如其名称所示,返回它们参数的平方和立方。factorial() 函数返回给定数字的阶乘

  3. 在现有函数下方,添加以下事件处理程序,实现打印文本输入框中数字信息的功能:

    js
    input.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)}. `;
      }
    });
    
  4. 保存代码,在浏览器中加载并测试。

下面是对上述步骤 3 中的 addEventListener 函数的一些解释:

  • 通过为 change 事件添加监听器,当文本输入框的值发生变化并提交时(例如输入值后,通过按 TabReturn 移出输入焦点),该匿名函数会执行。函数运行时,输入框的值会被存入常量 num。
  • if 语句在输入值非数字时显示错误信息。条件判断使用 isNaN(num) 检测是否为 trueisNaN() 检查 num 值是否不为数字 —— 如果不为数字,则返回 true,否则返回 false
  • 若条件返回 false,则 num 是有效数字,函数会在段落元素中输出该数字的平方、立方和阶乘值。这些值通过调用 squared()cubed()factorial() 函数计算得出。

备注: 若示例运行失败,可对比 GitHub 上的完成版(或查看实时演示),也可联系我们寻求帮助。

轮到你了!

现在,尝试编写自己的函数并添加到函数库中。比如计算平方根、立方根,或给定半径的圆周长?

附加函数编写建议:

  • 学习其他函数的错误处理示例。建议验证必要参数,并为可选参数提供默认值,以减少程序报错。
  • 考虑创建函数库。随着编程经验积累,你会重复使用某些功能。建立自己的工具函数库是高效的选择,可轻松移植到新项目或直接应用于 HTML 页面。

技能测试

本文已结束,你是否掌握了核心知识?可通过函数测试检验成果。

总结

函数既有趣又实用。尽管涉及大量语法和功能细节,但其核心概念易于理解。

如有疑问,可随时重读本文或联系我们寻求帮助。

参见

  • 深入了解函数——涵盖高阶函数知识的详细指南。
  • JavaScript 的回调函数——常见的 JavaScript 模式是将函数作为参数传入另一函数并在内部调用。这有点超出本课程的范围,但值得在不久之后进行研究。