JavaScript 函数、递归、闭包、箭头函数

134 阅读3分钟

函数是 JavaScript 中的基本组件之一。JavaScript 中的函数类似于过程——一组执行任务或计算值的语句。但要成为函数,这个过程应该接受输入并返回与输入存在某些明显关系的输出。要使用一个函数,你必须将其定义在你希望调用它的作用域内。

定义函数

一个函数定义(也称为函数声明,或函数语句)由 [function] 关键字,并跟随以下部分组成:

  • 函数名称。
  • 函数参数列表,包围在括号中并由逗号分隔。
  • 定义函数的 JavaScript 语句,用大括号括起来,{ /* … */ }
// 函数 square 接收一个 number 参数
function square(number) {
  return number * number;
}
调用函数

调用square并传递参数5。 函数执行完它的语句会返回值 25

square(10)
递归

一个函数可以指向并调用自身。调用自身的函数我们称之为 递归函数。在某种意义上说,递归近似于循环。两者都重复执行相同的代码,并且两者都需要一个终止条件(避免无限循环)。

function loop(x) {
  // “x >= 10”退出条件
  if (x >= 10) {
    return;
  }
  // 做些什么
  loop(x + 1); // 递归调用
}
loop(0);
闭包

闭包是 JavaScript 中最强大的特性之一。JavaScript 允许函数嵌套,并且内部函数具有定义在外部函数中的所有变量和函数(以及外部函数能访问的所有变量和函数)的完全访问权限。

但是,外部函数却不能访问定义在内部函数中的变量和函数。这给内部函数的变量提供了一种封装。

此外,由于内部函数可以访问外部函数的作用域,因此当内部函数生存周期大于外部函数时,外部函数中定义的变量和函数的生存周期将比内部函数执行的持续时间要长。当内部函数以某一种方式被任何一个外部函数之外的任何作用域访问时,就会创建闭包。

// 外部函数定义了一个名为“name”的变量
const pet = function (name) {
  const getName = function () {
    // 内部函数可以访问外部函数的“name”变量
    return name;
  };
  return getName; // 返回内部函数,从而将其暴露给外部作用域
};
const myPet = pet("Vivie");

console.log(myPet()); // "Vivie"

闭包实际上可能会比上面的代码复杂的多。它可以返回一个包含用于操作外部函数的内部变量的方法的对象。

箭头函数

箭头函数表达式(也称胖箭头,以区分未来 JavaScript 中假设的 -> 语法)相比函数表达式具有较短的语法且没有它自己的 this、arguments、super 和 new.target。箭头函数总是匿名的。 有两个因素会影响对箭头函数的引入:更简洁的函数和 this 的无绑定性。

const a = ["Hydrogen", "Helium", "Lithium", "Beryllium"];

// 在一些函数模式中,更简洁的函数很受欢迎。对比一下:
const a2 = a.map(function (s) {
  return s.length;
});
console.log(a2); // [8, 6, 7, 9]

const a3 = a.map((s) => s.length);
console.log(a3); // [8, 6, 7, 9]