📜  js 是函数 - Javascript (1)

📅  最后修改于: 2023-12-03 14:43:32.172000             🧑  作者: Mango

JS是函数 - JavaScript

JavaScript是一种高级编程语言,主要用于在网页上为用户提供动态交互体验。与其他编程语言不同的是,JavaScript也被视为一种函数式编程语言。这篇文章将介绍JS是如何函数式编程的。

函数在JS中的地位

在JS中,函数被看作是第一类对象(First-Class Object),也就是说它和其他的数据类型一样,可以用来赋值给变量,作为函数参数和返回值。

函数作为变量:

let greet = function(name) {
  console.log('Hello ' + name + '!');
};

greet('Alice'); // Hello Alice!

函数作为参数:

let add = function(a, b) {
  return a + b;
};

let calculator = function(opr, a, b) {
  return opr(a, b);
};

console.log(calculator(add, 2, 3)); // 5

函数作为返回值:

let getReminderFn = function(divisor) {
  return function(dividend) {
    return dividend % divisor;
  };
};

let reminderOf5 = getReminderFn(5);
console.log(reminderOf5(12)); // 2
高阶函数

高阶函数(Higher-Order Function)是指接受一个或多个函数作为参数,并且/或者返回一个函数的函数。

例如, map()filter()reduce() 都是高阶函数,它们接受一个函数作为参数。

let a = [1, 3, 5, 7, 9];
let squares = a.map(function(x) {
  return x * x;
});

console.log(squares); // [1, 9, 25, 49, 81]
let a = [1, 3, 5, 7, 9];
let evens = a.filter(function(x) {
  return x % 2 == 0;
});

console.log(evens); // []
let a = [1, 3, 5, 7, 9];
let sum = a.reduce(function(acc, val) {
  return acc + val;
});

console.log(sum); // 25
纯函数

在函数式编程中,纯函数是指不对外部状态做任何更改,并且对于相同的输入总是返回相同的输出的函数。

例如,函数 reverse() 并不是纯函数,因为它会改变输入数组。而函数 slice() 就是一个纯函数,因为它只是返回输入数组的子数组,并不改变原数组。

纯函数具有以下优点:

  • 更易于测试,因为相同的输入总是返回相同的输出;
  • 更容易推理和理解,因为它们只通过输入和输出来定义;
  • 更容易组合,因为它们不会有任何意外副作用。
尾调用优化

编译器可以对尾部递归函数进行优化,使得它们在运行时只占用一个堆栈帧。这样可以避免栈溢出的问题,使得递归函数在不增加内存负担的情况下可以处理更多的数据。

下面是一个朴素的阶乘实现:

function factorial(n) {
  if (n === 0) {
    return 1;
  } else {
    return n * factorial(n - 1);
  }
}

console.log(factorial(5)); // 120

该实现是非尾递归的。在计算5!的时候,调用栈的深度为5。如果n的值非常大,那么递归的深度也将迅速增加,可能会导致栈溢出的问题。

现在,我们可以使用尾调用优化将其转化为尾递归实现:

function factorial(n, acc = 1) {
  if (n === 0) {
    return acc;
  } else {
    return factorial(n - 1, acc * n);
  }
}

console.log(factorial(5)); // 120

由于 factorial() 最后一步只是返回同样的函数调用,并且它不会增加栈的深度,所以这个实现是尾递归的。在计算5!的时候,调用栈的深度仅为1。

参考文献