龙空技术网

JavaScript 中的 ‘return’ 是什么意思?

前端小玫 80

前言:

现时看官们对“js循环中return作用”都比较关怀,咱们都需要学习一些“js循环中return作用”的相关知识。那么小编也在网络上汇集了一些有关“js循环中return作用””的相关资讯,希望姐妹们能喜欢,朋友们快快来了解一下吧!

最近朋友问了我一个问题:“JavaScript 中的return是什么意思?”

function contains(px, py, x, y) {  const d = dist(px, py, x, y);  if (d > 20) return true; // 这行是什么意思?  else return false; // 那这一行呢?}

一开始我觉得这个问题很简单,但它背后其实蕴藏了一些重要且有趣的概念!

两种函数

我先解释了有 return 和没有 return 的函数的区别。函数是一组指令,如果你需要这组指令的执行结果,就需要一个 return 语句,否则不需要。

例如,要获得两个数的和,你应该声明一个带有 return 语句的 add 函数:

function add(x, y) {  return x + y; // 带有 return 语句}

然后你可以这样使用add函数:

const a = 1;const b = 2;const c = add(a, b); // 3const d = add(b, c); // 5

如果你只是想在控制台打印一条消息,则不需要在函数中使用return语句:

function great(name) {  console.log(`Hello ${name}!`);}

你可以这样使用great函数:

great('Rachel');

我原以为我已经解答了朋友的问题,但她又提出了一个新问题:“为什么我们需要这个求和函数?我们可以在任何地方写a + b,那为什么还要用return语句?”

const a = 1;const b = 2;const c = a + b; // 3const d = b + c; // 5

此时,我意识到她的真正问题是:“我们为什么需要函数?”

为什么需要函数?

为什么要使用函数?尽管有经验的程序员有无数的理由,这里我只关注一些与我朋友问题相关的原因。让我们探讨一下能够解答她好奇心的关键好处。

可重用的代码

她的确有道理。我们可以轻松地在任何地方写a + b。然而,这仅仅因为加法是一个简单的操作。如果你想执行一个更复杂的计算呢?

const a = 1;const b = 2;// 这是否易于在每个地方写?const c = 0.6 + 0.2 * Math.cos(a * 6.0 + Math.cos(d * 8.0 + b));

如果你需要多个语句来获得结果呢?

const a = 1;const b = 2;// t 是一个临时变量const t = 0.6 + 0.2 * Math.cos(a * 6.0 + Math.cos(d * 8.0 + b));const c = t ** 2;

在这两种情况下,重复编写这些代码会很麻烦。对于这种可重用的代码,你可以将其封装在一个函数中,这样每次需要它时就不必重新实现了!

function theta(a, b) {  return 0.6 + 0.2 * Math.cos(a * 6.0 + Math.cos(d * 8.0 + b));}const a = 1;const b = 2;const c = theta(a, b);const d = theta(b, c);
易于维护

在讨论可重用性时,你无法忽视可维护性。唯一不变的是世界总是在变化,这对于代码也一样!你的代码越容易修改,它就越具可维护性。

如果你想在计算结果时将0.6改为0.8,没有函数的情况下,你必须在每个执行计算的地方进行更改。但如果有一个函数,你只需更改一个地方:函数内部!

function theta(a, b) {  // 将 0.6 更改为 0.8,你就完成了!  return 0.8 + 0.2 * Math.cos(a * 6.0 + Math.cos(d * 8.0 + b));}

毫无疑问,函数增强了代码的可维护性。就在我以为我解答了她的问题时,她又提出了另一个发人深省的问题:“我理解了函数的必要性,但为什么我们需要写 return?”

为什么需要return?

真有意思!我之前没有考虑过这个问题!她随后提出了一些关于return的替代方案,这些想法非常有创意!

为什么不直接返回最后一条语句?

第一个建议的方案是“为什么不直接返回最后一条语句?”

function add(a, b) {  a + b}const sum = add(1, 2); // undefined

我们知道,在 JavaScript、Java、C 或许多其他语言中,这样是不允许的。这些语言的规范要求显式的return语句。然而,在某些语言中,例如 Rust,这是允许的:

fn add(a: i32, b: i32) -> i32 {    a + b}let sum = add(1, 2); // 3

然而值得注意的是,JavaScript 中的另一种函数类型不需要return语句!那就是带有单个表达式的箭头函数

const add = (x, y) => x + y;const sum = add(1, 2); // 3
如果我们将结果赋值给局部变量呢?

然后她提出了另一个有创意的解决方案:“如果我们将结果赋值给一个局部变量呢?”

function add(x, y) {  let sum = x + y;}add(1, 2);sum; // Uncaught ReferenceError: sum is not defined

她很快注意到我们无法访问 sum 变量。这是因为使用 let 关键字声明的变量只在其定义的作用域内可见——在这个例子中是函数作用域。

可以将函数视为黑盒子。你将参数放入盒子中,期待获得一个输出(返回值)。只有返回值对外部世界(父作用域)是可见的(或可访问的)。

将结果赋值给全局变量呢?

如果我们在函数作用域之外访问这个值呢?将其赋值给一个全局变量怎么样?

let sum;function add(x, y) {  sum = x + y;}add(1, 2);sum; // 3

啊,修改全局变量!副作用!非纯函数!这些想法在我脑海中浮现。但我如何在一分钟内解释为什么这是一个糟糕的选择呢?

避免这种方法的一个关键原因是,别人很难知道具体的全局变量是在哪个函数中被修改的。他们需要去查找结果在哪儿,而不是直接从函数中获取!

总结

简而言之,我们需要 return,因为我们需要函数,而在 JavaScript 中的标准函数中没有可行的替代方案。

函数的存在是为了使代码具有可重用性和可维护性。由于 JavaScript 的规范、函数作用域的限制以及修改全局变量带来的风险,我们在 JavaScript 的标准函数中必须使用 return 语句。

这次讨论非常有趣!我从未想过看似简单的问题背后竟然蕴含着如此多的复杂思考。与不同视角的人交流总能带来新的见解!

标签: #js循环中return作用