前端函数式编程简史01 开篇

105 阅读3分钟

什么是函数式编程 ?

函数式编程是一种编程范式,它将一个程序看做一系列的函数调用,把计算过程看作数学函数的应用。

核心概念是:

  1. 无副作用:函数的返回值只依赖于输入参数,不会受外部状态的影响,也不会改变外部状态;
  2. 可组合:函数可以组合起来,构成新的函数;
  3. 高阶函数:可以将函数作为参数传入另一个函数,也可以将函数作为返回值返回。

个人理解:

函数式编程(Functional Programming)是一种编程范式,它的核心概念是以函数作为一等公民(First-class citizen),即函数可以像其它数据类型一样进行传递、赋值和作为参数传入另一个函数,它主要依赖的技术有:函数组合(Function composition)、闭包(Closure)、高阶函数(Higher-order function)、函数递归(Function recursion)、不可变性(Immutability)等。

javascript 函数式编程基本例子

无副作用,函数的返回值之依赖于输入参数


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

函数可以作为值传递

let sum = add; 

将函数可以作为参数传入另一个函数:

function operate(op, a, b) { return op(a, b); } 
let result = operate(sum, 1, 2); 
console.log(result); // 3 

高阶函数:可以将函数作为参数传入另一个函数,也可以将函数作为返回值返回


function add(x, y) { return x + y; } 

function higherOrderFunction(f, x, y) { return f(x, y); }

在React中应用高阶函数


// 在 React 中,我们可以使用高阶函数来封装组件,以实现更复杂的功能: 
import React from 'react'; 

// 定义一个高阶组件 通常以with开头
    function withToggle(Component) { 
      return function(props) { 
                return <Component {...props} toggle={/* 添加toggle功能 */}/>;          
             }; 
    }

// 使用高阶组件 
   function MyComponent(props) { 
       const { toggle } = props; 
       return <button onClick={toggle}>Toggle</button>; 
   } 
    export default withToggle(MyComponent);

React Hooks 是一种对 React 组件的逻辑的抽象,可以使用高阶函数将状态管理、副作用处理等逻辑从组件中抽离出来,实现代码复用。下面是一个使用高阶函数实现状态管理的例子:


import React, { useState } from 'react';
function useCounter(initialState) {
    const [count, setCount] = useState(initialState);
    const increment = () => setCount(count + 1);
    const decrement = () => setCount(count - 1);
    return { count, increment, decrement };
}
function Counter() {
    const { count, increment, decrement } = useCounter(0);
    return (<div>
        <span>{count}</span>
        <button onClick={increment}>+</button>
        <button onClick={decrement}>-</button>
    </div>
    );
}

export default Counter

在上面的例子中,我们通过使用高阶函数来抽离出状态管理逻辑,使 Counter 组件更加简洁、易于维护。

React 的 useEffect 钩子函数就是一个高阶函数,它接受一个函数作为函数来执行副作用(所谓副作用,就是不依赖于函数传入参数,导致的函数结果发生了变化),它可以被用于在 React 组件外部做一些副作用处理(如访问 DOM 节点,获取数据等),以及在某些特定的条件下进行状态更新。 举个例子:

import React, { useState, useEffect } from 'react';

function Example() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        // 每次渲染时,都会执行 
        document.title = `You clicked ${count} times`;
    });

    return (
        <div> 
            <p>You clicked {count} times</p> 
            <button onClick={() => setCount(count + 1)}> Click me </button> 
        </div>
    );
}

在上面的例子中,useEffect 钩子函数就是一个高阶函数,它可以在 React 组件外部更新文档标题,以及根据 count 的变化来更新文档标题。

但是会引入闭包问题,请听下回分解