欢迎光临
我们一直在努力

跟着 MDN 学JavaScript day_19:函数返回值

引言

在前面两篇文章中,我们学习了函数的基本概念,并亲手创建了自定义函数。但到目前为止,我们创建的函数主要是在执行一些操作,比如在页面上显示消息框,而并没有将任何处理结果反馈给调用者。在实际编程中,很多函数的作用不仅仅是执行某个动作,更重要的是完成某种计算并将结果传递回来,供后续代码使用。这种函数执行完毕后回传的结果就是返回值。


一、什么是返回值

返回值这个词非常直白,它指的就是函数执行完毕后返回的那个值。虽然你可能没有刻意思考过这个概念,但在之前的学习中你已经无数次接触过返回值了。每当你在代码中调用一个函数,并将它的结果赋值给一个变量,或者直接使用它的结果进行其他操作时,你就在使用返回值。

1.1 熟悉的例子

const myText = "天气很冷";
const newString = myText.replace("冷", "热");
console.log(newString); // 输出 "天气很热"

在这段代码中,myText.replace("冷", "热") 这个函数调用执行后,返回了一个新字符串 "天气很热"。这个返回值被赋值给了 newString 变量。如果���们不把返回值存起来,这个新字符串就会丢失,因为它只是临时产生的一个值。

在MDN文档中查阅任何一个函数的说明页面,你都会找到一个名为"返回值"的专门章节。文档编写者深知理解返回值对于正确使用函数至关重要,养成查阅文档中返回值说明的习惯,能让你少走很多弯路。


二、有返回值与无返回值的函数

并不是所有函数都有有意义的返回值。在我们的参考文档中,有些函数的返回值被标记为空值 void 或未定义值 undefined,这意味着这个函数执行完毕后不会回传任何有用的数据。

// 无返回值的函数:只执行操作(副作用),不返回数据
function displayMessage(msgText, msgType) {
const html = document.querySelector("html");
const panel = document.createElement("div");
panel.setAttribute("class", "msgBox");
html.appendChild(panel);

const msg = document.createElement("p");
msg.textContent = msgText;
panel.appendChild(msg);

const closeBtn = document.createElement("button");
closeBtn.textContent = "x";
panel.appendChild(closeBtn);

closeBtn.onclick = function () {
panel.parentNode.removeChild(panel);
};
// 没有 return 语句 → 默认返回 undefined
}

// 有返回值的函数:计算并返回结果
function squared(num) {
return num * num;
}

类型特征示例
无返回值函数 执行副作用操作,没有 return 语句或返回 undefined displayMessage()
有返回值函数 通过 return 回传计算结果 squared(num)

有返回值的函数通常被用作计算的中间步骤。一个函数处理完数据后返回结果,这个结果可以作为另一个函数的输入,形成处理管道。这种链式处理数据的方式是函数式编程思想的体现。


三、使用return关键字

要从自定义函数中返回值,你需要使用 return 关键字。return 语句有两个作用:

作用说明
指定返回值 return 后面的表达式的值就是函数的返回值
终止函数执行 一旦执行到 return,函数立即停止运行,之后的代码不会被执行

3.1 基本示例

我们之前见过的一个实际例子来自 random-canvas-circles.html:

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

这个函数接收一个整数参数 number,函数体只有一行 return 语句:

  • Math.random() 生成一个 [0, 1) 的随机小数
  • 乘以 number 后得到 [0, number) 的随机小数
  • Math.floor() 向下取整,得到 [0, number-1] 的随机整数
  • 最终结果通过 return 返回给调用者
  • 3.2 两种写法对比

    // 写法一:直接在 return 中计算(更简洁)
    function randomNumber(number) {
    return Math.floor(Math.random() * number);
    }

    // 写法二:先计算再返回(更易读,适合复杂逻辑)
    function randomNumber(number) {
    const result = Math.floor(Math.random() * number);
    return result;
    }

    两种写法功能完全相同。当计算逻辑比较复杂时,先计算再返回可能让代码更容易理解。

    3.3 "函数调用被返回值替换"的思维模型

    理解这种思维模型非常重要。比如在 draw 函数中调用了三次 random:

    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);

    执行流程:

    random(WIDTH) → 计算 → 返回 500 → 替换调用位置
    random(HEIGHT) → 计算 → 返回 200 → 替换调用位置
    random(50) → 计算 → 返回 35 → 替换调用位置
    → ctx.arc(500, 200, 35, 0, 2 * Math.PI) → 执行

    JavaScript引擎会先执行函数调用,获取返回值,然后用返回值替换掉函数调用的位置,最后再执行外层语句。


    四、主动实践:构建带返回值的函数库

    理论知识讲再多也不如亲手写一遍。让我们构建一个简单的函数库,包含几个数学计算函数,每个函数都接收参数并返回计算结果。

    4.1 三个计算函数

    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(5) 计算平方 5 * 5 25
    cubed(5) 计算立方 5 * 5 * 5 125
    factorial(5) 计算阶乘 5 × 4 × 3 × 2 × 1 120

    factorial 函数的实现使用了 while 循环来累乘:

    // 以 factorial(5) 为例,执行流程:
    // 初始:num=5, x=5
    // 第1次循环:num=5×(5-1)=20, x=4
    // 第2次循环:num=20×(4-1)=60, x=3
    // 第3次循环:num=60×(3-1)=120, x=2
    // 第4次循环:num=120×(2-1)=120, x=1
    // x>1 为 false,循环终止
    // return 120

    4.2 事件监听与输入处理

    为了让这些函数真正工作起来,需要监听输入框的变化事件:

    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)}. `;
    }
    });

    事件处理流程:

    用户输入 → "change"事件触发

    parseFloat(input.value) 将字符串转为浮点数

    isNaN(num)?
    ├─ true → 显示错误提示 "You need to enter a number!"
    └─ false → 依次调用三个函数,用返回值拼接输出字符串

    关键函数作用
    parseFloat() 将字符串解析为浮点数,无法解析时返回 NaN
    isNaN() 检测一个值是否为 NaN,是则返回 true

    这个输入验证很重要——如果用户在输入框中输入了字母或其他非数字内容,parseFloat 会返回 NaN,而用 NaN 进行数学运算会导致所有结果都变成 NaN,产生无意义的输出。

    这里可以看到返回值的实际运用:每个函数调用都返回一个数值,这些数值直接在字符串模板中被拼接显示。如果没有返回值机制,我们需要在每个函数内部直接操作DOM来显示结果,代码会变得混乱且难以复用。


    五、函数库的思维与错误处理

    5.1 函数库的概念

    当你能熟练编写自己的函数后,自然会产生构建个人函数库的想法。函数库就是一组相关函数的集合,可以保存在一个单独的JavaScript文件中,在需要的时候引入使用。

    math-utils.js
    ├── squared(num) // 计算平方
    ├── cubed(num) // 计算立方
    ├── factorial(num) // 计算阶乘
    ├── isPrime(num) // 判断质数
    └── gcd(a, b) // 计算最大公约数

    5.2 防御性编程

    在编写函数时,养成良好的错误处理习惯非常重要:

    // 带防御性检查的平方函数
    function squared(num) {
    if (num === undefined || num === null) {
    console.warn("squared() 缺少参数");
    return 0; // 返回合理的默认值
    }
    return num * num;
    }

    原则说明
    验证必要参数 缺少关键参数时给出提示或返回默认值
    提供参数默认值 可选参数使用 param = defaultValue
    清晰的函数命名 如 squared 准确传达"计算平方"的含义

    六、总结

    函数返回值是JavaScript函数体系中最后一个基础概念,但它绝不是最不重要的。有了返回值,函数就不再只是执行操作的孤立代码块,而是变成了可以串联组合的数据处理单元。

    核心要点回顾

    知识点核心内容
    返回值定义 函数执行完毕后回传给调用者的值
    return 关键字 指定返回值 + 终止函数执行
    无返回值函数 执行副作用操作,默认返回 undefined
    替换思维模型 函数调用被返回值替换,再执行外层语句
    链式处理 一个函数的返回值作为另一个函数的输入
    错误处理 验证参数、提供默认值、防御性编程

    完整代码回顾

    // ====== 函数定义 ======
    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;
    }

    // ====== 事件绑定 ======
    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)}. `;
    }
    });

    如果本文中有任何概念让你感到困惑,不要犹豫,重新阅读相关章节或者动手在浏览器控制台中试验代码。编程学习最好的方式就是亲手实践。在后续的学习中,你还会接触到更高级的函数概念,比如将函数作为参数传递给另一个函数的回调函数模式,以及能够返回函数的函数。这些进阶内容都建立在扎实的基础概念之上,现在打好基础,未来的学习就会水到渠成。

    赞(0)
    未经允许不得转载:171主机测评 » 跟着 MDN 学JavaScript day_19:函数返回值
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址