Web前端高级工程师培训:函数式编程

news2024/10/21 7:10:54

函数式编程

  • 前置知识
    • js 基础
    • js面向对象

函数式编程含义

  • 函数式编程是一种强调以函数使用为主的软件开发风格 ,也是一种范式。

  • 某些函数式编程语言Haskell、lisp、Scheme等。

js中函数式编程

  • 数学中函数

    f(x) = y;

  • js中的函数

       let factor = 3;
       let totalNum = num=>factor*num;
       console.log( totalNum(3) );
    
  • 对比两种函数,基于数学函数 来修复 js函数

       let totalNum = (num,factor)=>factor*num;
       console.log( totalNum(3,3) );
    
  • js是多范式编程语言,但是函数作为一等公民,函数式编程具有天然优势。

###函数式编程中涉及到的概念

####纯函数

  • 函数式编程基于纯函数

    • 纯函数是对给定的输入返还相同输出的函数;例如

      let double = value=>value*2;
      
  • 纯函数意义

    • 纯函数可以产生可测试的代码

      • 不依赖外部环境计算,不会产生副作用,提高函数的复用性。

        test('double(2) 等于 4', () => {
          expect(double(2)).toBe(4);
        })
        
    • 可读性更强 ,js函数不管是否是纯函数 都会有一个语义化的名称,更便于阅读。

    • 可以组装成复杂任务的可能性。符合模块化概念及单一职责原则。

高阶函数

  • 高阶函数定义

    • 高阶函数:以函数作为输入或者输出的函数被称为高阶函数(Higher-Order Function)。
  • 高阶函数的抽象

    • 一般高阶函数用于抽象通用问题,简而言之,高阶函数就是定义抽象。

      • 命令式循环(注重“如何”做,注重过程);

        let arr = [1,2,3];
        for(let i=0;i<arr.length;i++){
            console.log(arr[i]);
        }
        
      • 通过高阶函数抽象过程,声明式编程(注重做“什么”,注重结果);

        const forEach = function(arr,fn){
            for(let i=0;i<arr.length;i++){
                fn(arr[i]);
            }
        }
        let arr = [1,2,3];
        forEach(arr,(item)=>{
            console.log(item);
        })
        

        上面通过高阶函数 “forEach”来抽象循环"如何"做的逻辑,直接关注 做"什么"

  • 高阶函数的缓存特性

    • 主要是利用函数的闭包

      • once 高阶函数
      const once = (fn)=>{
          let done = false;
          return function(){
              if(!done){
                  fn.apply(this,fn);
              }else{
                  console.log("this fn is already execute");
              }
              done = true;
          }
      }
      
      function test(){
          console.log("test...");
      }
      let myfn =  once(test);
      myfn();
      myfn();
      

柯里化

  • 什么是柯里化?

    • 柯里化是把一个多参数函数转化成一个嵌套的一元函数的过程;

      • 如下二元函数

        let fn = (x,y)=>x+y;
        
      • 柯里化函数

        const curry = function(fn){
            return function(x){
                return function(y){
                    return fn(x,y);
                }
            }
        }
        let myfn = curry(fn);
        console.log( myfn(1)(2) );
        
  • 多参数函数柯里化

    // 多参数柯里化;
        const curry = function(fn){
            return function curriedFn(...args){
                if(args.length<fn.length){
                    return function(){
                        return curriedFn(...args.concat([...arguments]));
                    }
                }
               return fn(...args);
            }
        }
        const fn = (x,y,z,a)=>x+y+z+a;
        const myfn = curry(fn);
        // console.log(myfn(1)(2));
        console.log(myfn(1)(2)(3)(1));
    
  • 柯里化意义

    • 让纯函数更”纯“,每次接受一个参数,松散解耦
    • 某些语言及特定环境下只能接受一个参数
    • 惰性执行

组合(composition)和管道(pipe)

####组合(composition)

  • 组合函数:无需创建新的函数,通过基础函数解决眼前问题。

    • 组合高阶函数 map 及 filter;

      • map高阶函数

      • 组合map及filter来使用

    • compose组合

      可以封装组合函数来实现函数执行

      • 2个函数组合
      function afn(a){
          return a*2;
      }
      function bfn(b){
          return b*3;
      }
      const compose = (a,b)=>c=>a(b(c));
      let myfn =  compose(afn,bfn);
      console.log( myfn(2));
      
      • 多函数组合

        const compose = (...fns)=>val=>fns.reverse().reduce((acc,fn)=>fn(acc),val);
        

管道(pipe)

compose 执行是从右到左,pipe是从左至右的执行。函数如下:

const pipe = (...fns)=>val=>fns.reduce((acc,fn)=>fn(acc),val);

​ 管道、组合 取舍 :管道及组合最大区别在于执行顺序的不同,数据流向不同,达到目的是类似的。所以无优 劣之分,保持团队风格统一就好了。

组合及管道的意义 把很多小函数组合起来完成更复杂的逻辑。

Pointfree 编程风格

概念:不适用处理的值,只合成运算过程,也就是无值风格。

  • 获取所有的句号

    const sentenceNum = str=>str.match(//g);
    let str = "大家好,我是中国人。我爱中国。我们同住地球村。";
    console.log(sentenceNum(str));
    
  • 统计长度

    const countFn = arr=>arr.length;
    
  • 判断奇偶

    const oddOrEven = num=>num%2===0?"偶数":"奇数";
    
  • pointfree风格组合函数使用:找到句号统计长度最后判断奇偶数

    let str = "大家好,我是中国人。我爱中国。我们同住地球村。";
    const myfn = compose(oddOrEven,countFn,sentenceNum);
    console.log(myfn(str));
    

js函数式编程库

  • lodash.js 、ramda.js 、Underscore.js

  • 通过 ramda.js实现数据筛选功能;

##函数式编程在redux 中应用

  • Redux 整体是通过函数式 编程思维实现的;

  • createStore 简单实现

    const createStore = (reducer, initialState) => {
        const store = {};
        let  currentState = initialState;
        const  listeners = [];
        const getState = () => currentState;
        const subscribe = (listener) => {
            listeners.push(listener);
        };
        const dispatch = (action) => {
            // store.state = deepFreeze(reducer(store.state, action) );
            currentState = reducer(currentState, action);
            listeners.forEach(listener => listener());
        };
        return {
            getState,
            subscribe,
            dispatch
        };
    };
    
    export {createStore}; 
    
  • 状态管理调用

    import {createStore} from "../MyRedux.js";
    // import { createStore } from 'redux';
    function Counter(state={count:0},action) {
        switch (action.type) {
            case "ADD_COUNT":
                return {count:state.count + 1}
                break;
            case "REDUCE_COUNT":
                return {count:state.count - 1}
                break;
            default:
                return state;
                break;
        }
    }
    var store = createStore(Counter);
    
    
    btn.onclick = function(){
        // console.log(store);
        store.dispatch({type:"ADD_COUNT"});
    }
    
    store.subscribe(() => {
        // console.log(store)
        renderDom()
    })
    
    function renderDom(){
      let mydiv =   document.querySelector(".countDiv");
      if(typeof store.getState() !== "undefined"){
        mydiv.innerHTML = store.getState().count;
      }
    }
    

函子

容器函子Functor

函子是函数式编程里面最重要的数据类型,也是基本的运算单位和功能单位。

  • 定义自己的Functor。

    class Container{
        constructor(value){
            this._value = value;
        }
        static of(val){
            return new Container(val);
        }
    }
    let res = Container.of(1);
    console.log(res);
    
  • 通过map修改Functor值

class Container{
    constructor(value){
        this._value = value;
    }
    static of(val){
        return new Container(val);
    }
    map(fn){
        return Container.of(fn(this._value));
    }
}
let res = Container.of(1);
// console.log(res);
let reslut =  res.map(item=>{
    // console.log(item);
   return item+3
}).map(item=>{
    return "最终结果是" + item;
})

MeBe函子

处理空值的函子

class Mabe{
    constructor(val){
        this._value = val;
    }
    static of(val){
        return new Mabe(val);
    }
    isNoThing(){
        return (this._value===null || this._value=== undefined);
    }
    map(fn){
        return this.isNoThing()?Mabe.of(null):Mabe.of(fn(this._value));
    }
}

Either 函子

class Either extends Functor{
    constructor(left,rigth){
        super();
        this.left = left;
        this.right = rigth;
    }
    map(f){
        return this.right?Either.of(this.left, f(this.right)) :
      Either.of(f(this.left), this.right);
    }
    static of(left, right){
        return new Either(left, right);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2219876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

堆的使用实例

小伙伴们大家好&#xff0c;今天为大家带来一道算法题&#xff1a; 分析题意我们可知&#xff1a;数组最小元素一定位于0~k位置&#xff0c;如果我们首先将0~k位置构成最小堆&#xff0c;那么堆顶一定就是数组最小值。将堆顶拿出&#xff0c;将数组k1位置放入&#xff0c;那么数…

无人机+视频推流直播EasyCVR视频汇聚/EasyDSS平台在森林防护巡检中的解决方案

随着科技的飞速发展&#xff0c;无人机技术在各个领域的应用日益广泛&#xff0c;特别是在森林防护与巡检方面&#xff0c;无人机以其独特的优势&#xff0c;为传统林业管理带来了革命性的变化。本文将探讨无人机在森林防护巡检中的解决方案&#xff0c;分析其工作原理、优势及…

MYSQL 拼接函数

目录 1、CONCAT 2、CONCAT_WS 1、CONCAT 解释&#xff1a;用于拼接两个或多个字符串成一个字符串。如果任何一个参数为 NULL&#xff0c;则 CONCAT 函数的结果也会是 NULL。 语法格式&#xff1a;SELECT concat(column_name1,column_name2,...) FROM table_name 中文注释&…

【verilog刷题】时钟切换电路

时钟切换电路 1.基本概念-相关时钟源和无关时钟源2.基本的时钟切换电路&#xff08;组合逻辑&#xff09;2.相关时钟源无毛刺时钟切换电路3.非相关时钟源无毛刺时钟切换电路 1.基本概念-相关时钟源和无关时钟源 相关时钟源&#xff1a;时钟信号源之间存在某种同步或关联的关系…

[含文档+PPT+源码等]精品基于Nodejs实现的医院问诊系统的设计与实现

基于Node.js实现的医院问诊系统的设计与实现背景主要源于以下几个方面&#xff1a; 一、医疗行业变革的需求 随着互联网的飞速发展&#xff0c;特别是移动互联网技术的广泛应用&#xff0c;传统医疗行业正经历着前所未有的变革。医疗资源分布不均、患者就医难等问题日益凸显&…

数据结构单向链表的插入和删除(一)

链表 一、链表结构&#xff1a; &#xff08;物理存储结构上不连续&#xff0c;逻辑上连续&#xff1b;大小不固定&#xff09;二、单链表&#xff1a;三、单项链表的代码实现&#xff1a;四、开发可用的链表&#xff1a;四、单链表的效率分析&#xff1a; 一、链表结构&#x…

爬虫结合项目实战

由于本人是大数据专业&#xff0c;所以准备的是使用pycharm工具进行爬虫爬取数据&#xff0c;然后实现一个可视化大屏 参考项目&#xff1a; 1.医院大数据可视化最后展示 2. 大数据分析可视化系统展示 代码包&#xff1a;

如何防止SpringBoot中的jar反编译?解决相关报错及踩到的坑

目录 1. 面对的场景 2. 方案 2.1 使用代码混淆 2.2 JAR包加密 3. 项目操作 4. 启动方式 5. 踩到的各种坑 5.1 java -jar xxx-0.0.1-SNAPSHOT.jar 没有主清单属性 5.2 Caused by: java.lang.IllegalArgumentException: Unrecognized option: -pwdfxw-jar 1. 面对的场景…

sql-labs靶场第十七关测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、寻找注入点 2、注入数据库 ①寻找注入方法 ②爆库&#xff0c;查看数据库名称 ③爆表&#xff0c;查看security库的所有表 ④爆列&#xff0c;查看users表的所有列 ⑤成功获取用户名…

STM32CubeMX【串口收发USART】

第一步&#xff0c;配置cubemx 配置好点右上角生成 第二步&#xff0c;串口方式 阻塞式发送 英文、中文正常、浮点有口 /* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();//配置完自动生成的 发送到串口助手上 while (1){/* USER CODE…

【计算机网络 - 基础问题】每日 3 题(五十)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

有限状态机和抽象类多态

学习有限状态机的写法&#xff0c;我们会用一个抽象类继承的方法来写 首先&#xff0c;现在我们已经用过类的继承了&#xff0c;就是在我们敌人和野猪的这个代码当中&#xff0c; 我们打开野猪的代码&#xff0c;它继承了Enemy这个父类&#xff0c;所以可以遗传它父类当中所有…

线性代数基础02

目录 1.向量 1.1向量的定义 1.2向量的运算 1.2.1向量加法 1.2.2向量数乘 1.2.3向量点积 1.3矩阵的特征值和特征向量 1.4向量的模 1.4.1向量的模的定义 1.4.2向量的模的几何解释 1.4.3向量的模的性质 1.5向量的内积 1.5.1向量的内积的定义 1.5.2向量的内积的几何解…

【Linux】进程概念 PCB结构体 fork创建子进程

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;青果大战linux 总有光环在陨落&#xff0c;总有新星在闪烁 每日小感慨&#xff…

UDP/TCP协议详解

目录 一,自定义应用层协议: 1)xml 2),JSON 3),yml 4),google protobuffer 二,传输层UDP/TCP: UDP协议: TCP协议: TCP的核心机制一:确认应答 TCP核心机制二:超时重传 TCP核心机制三:连接管理 TCP核心机制四:滑动窗口 TCP核心机制五:流量控制 TCP核心机制六:拥塞控制…

c++ pdf文件提取txt文本示例

最近抽空采用之前封装的接口将pdf文件提取出txt文本&#xff0c;顺利完成&#xff0c;界面如下所示&#xff1a; 提起的效果如下所示&#xff1a; 输出的txt文本内容如下&#xff1a; 下载链接&#xff1a;https://download.csdn.net/download/u011269801/89905548

AI 3D拣选系统行业分析:物流行业是最主要的需求来源

AI 3D拣选系统是一种集成了先进传感技术、机器人技术和计算机视觉技术的自动化分拣解决方案。它能够在三维空间内快速、准确地识别和分拣各种形状、大小和材质的物品&#xff0c;大大提高了物流效率和准确性。该系统通过高精度的3D传感器和先进的视觉算法&#xff0c;能够实时捕…

【某农业大学计算机网络实验报告】实验五 TCP 运输连接管理

实验目的&#xff1a; 熟悉 TCP 通信的三个阶段&#xff1a;通过此次实验&#xff0c;结合理论课知识深入理解并熟悉 TCP 通信的三个主要阶段&#xff0c;即连接建立&#xff08;SYN-SYN&#xff09;&#xff0c;数据传输&#xff08;DATA&#xff09;&#xff0c;以及连接释放…

【论文速读】Prompt Tuning:The Power of Scale for Parameter-Effificient Prompt Tuning

arxiv&#xff1a;2104.08691v2 摘要 在这项工作中&#xff0c;我们探索了“prompt tuning&#xff08;提示调优&#xff09;”&#xff0c;这是一种简单而有效的机制&#xff0c;用于学习“soft prompts&#xff08;软提示&#xff09;”&#xff0c;以条件下冻结的语言模型…

Golang | Leetcode Golang题解之第485题最大连续1的个数

题目&#xff1a; 题解&#xff1a; func findMaxConsecutiveOnes(nums []int) (maxCnt int) {cnt : 0for _, v : range nums {if v 1 {cnt} else {maxCnt max(maxCnt, cnt)cnt 0}}maxCnt max(maxCnt, cnt)return }func max(a, b int) int {if a > b {return a}return …