首页 > 编程语言 >JavaScript中的“函数式编程”

JavaScript中的“函数式编程”

时间:2023-08-21 12:33:06浏览次数:42  
标签:编程 console name title JavaScript log 数组 函数

前言

我们虽然之前老是听说过“函数式编程”,但一直不能理解,我们静下心来研究了一下,才发现这些东西真的很巧妙。

在React这些框架中,对象,函数为王,因为框架已经帮你打建好了

在框架中,数据为王,那些函数本身就是用来处理数据

这里我们要用更高层的思维,而放弃底层思维,这些本身都是用户数据,前段传递到后端,后端传递到前段

我们用固定的编写好的函数来处理数据返回数据,或者把函数传递到框架(函数),这思想要有。

甚至函数返回函数,为什么呢,因为一个函数也可以看做一个变量,直接把函数作为一个工具传递到另外一个函数中使用

 

一、不可变性

一个对象Object Person,当被创建出来之后,就不能被修改原件了,要修改,只能拷贝一份新的。

同理,数组也是一样的,我们要拷贝一份新的,所有的操作都在拷贝件上来进行。

函数式编程,函数为王,一切基于函数,这些转换基本都是在函数中发生的。

此时,你就理解“展开运算符”的作用了,如下面这个,我们直接创建了一个makeBackpackingMeals函数来帮助我们构造

makeBackpackingMeals是一个标准的纯函数,单纯用于数据转换,把它看做处理数据的工具,一切以数据为核心!! 

    const morning = {
        breakfast: "oatmeal",
        lunch: "peanut butter and jelly"
    };

    const dinner = "mac and cheese";

    makeBackpackingMeals = (morningFood, dinnerFood)=>{
        return {
            ...morningFood,
            dinnerFood
        }
    }

    packingMeals =  makeBackpackingMeals(morning, dinner)

    console.log(packingMeals);
    // {
    //     breakfast: "oatmeal",
    //     lunch: "peanut butter and jelly",
    //     dinner: "mac and cheese"
    // }

 

二、警惕 Array.push对原数组数据的修改和Array.concat方法的利用

如下,这是使用Array.push,我们发现其也会把原数组来修改,其哪怕在函数中也不行。

    let list = [
        { title: "Rad Red" },
        { title: "Lawn" },
        { title: "Party Pink" }
    ];

    var addColor = function(title, colors) {
        colors.push({ title: title });
        return colors;
    };

    //
    // Add Color is mutating the original list
    //

    console.log(addColor("Glam Green", list).length); // 4
    console.log(list.length); // 4

 此时,我们要是有 concat,拼接功能的数组,下面的例子中,使用concat,其表示两个数组拼接在一起。

这里不要想什么效率问题,太底层,你就拼接几个数组,数据量才多大,想啥效率,cpu那些破东西,数据为王

你有本事自己去优化代码啊,你自己又优化不了!!

    let list = [
        { title: "Rad Red" },
        { title: "Lawn" },
        { title: "Party Pink" }
    ];

    const addColor = (title, array) =>
        array.concat({ title });

    //
    // Use array.concat instead, it does not mutate the list
    //

    console.log(addColor("Glam Green", list).length); // 4
    console.log(list.length); // 3

这里有一个语法 {title} ,我们看参数名是一个title,而 concat({title}),我们拆分这个语句。

这是个变量名与变量值的问题,title是变量名,其title={Glam Green},而我们又有 title = "Glam Green"

相当于 {title:"Glam Green"},这个语法要理解,关键搞清楚变量名和变量值,以及{ } 运算符的使用技巧

看下面这个代码,很好理解,直接以一个人名来生成一个person,这个不难理解!!

    name = "Tom"
    person = {name}
    console.log(person) // {name: "Tom"}

 

三、函数式编程中的两个关键 Array.map, Array.reduce,Array.filter

 看看上面这两个例子,我们之前使用concat,这是做数组拼接,还有更复杂的方法。

Array中有两个关键函数,一个是对数组进行改变,转换成另一种新的数组,另外一个是对数组进行过滤

它们俩分别是 map 和 filter,我们下面来看看其用法,很简单。

它们都接收一个函数(其只有一个参数),执行时,把数组中的每个值传到里面执行一遍,然后再返回,依次这样执行下去。

 

 当你理解这个模型时,你发现这并没有那么难,你不用去想其怎么实现的,先要具象化,拷贝一份,然后

 如下,要读懂下列这个代码,要知道如何阅读代码:

1. 重点理解item,看见在map里,item就是变量名,每个数组之前是array[i] ,现在直接给单独拿出来,作为item的值来操作;

2. 这个箭头函数没有 { },所以后面指向的就是返回值,在map中,返回值直接就是新的数组的元素;

3. {...item, name} 中 name = "xxx",这个用法要知道,...item,展开,如果是对象,那么展成一个个 name = "xxx",然后重新构建一个对象。

用这种方法,我们不需要手动操作数组,你之后修改数组,要一直使用map这种写法,因为会成生成一份新的数组。

filter方法也是同理,我们现在将这代码给写好,其实一点不难,我们耐心做下去,很好理解。

    let schools = [
        { name: "Yorktown"},
        { name: "Stratford" },
        { name: "Washington & Lee"},
        { name: "Wakefield"}
    ]

    // Edit Name with less syntax

    const editName = (oldName, name, arr) =>
        arr.map(item => (item.name === oldName) ?
            {...item,name} :
            item
        )

    let updatedSchools = editName("Stratford", "HB Woodlawn", schools)

    console.log( updatedSchools[1] ) // {name: 'HB Woodlawn'}
    console.log( schools[1] ) // {name: 'Stratford'}

below的写法更直接,其函数要返回一个判断表达式,或者说bool值,如果为false,就丢弃。

我们这里直接 (val) => val < 5,不要单纯想着布尔值,关键我们的思维模式,把“val”是数组值,我们直接获取想要的这个值,不要丢弃

我们想的单纯点,避免陷入语法之中,这样写就很简洁,这才是抽象思维。

    array = [1,2,3,4,5,6,7,8,9,10]
    belowFiveItems = array.filter((val)=>val<5)
    console.log(belowFiveItems) //  [1,2,3,4]

Array.reduce

这个返回一个单独的值(single value),这个关键参数,一个是在之前中搜索出来的值,一个是当前的值;

类似依次比较,然后找出你想找出的值,看下面求最大数的例子,其实很好理解。

array = [1,2,3,4,5,6,7,8,9,10]

    maxValue = array.reduce((curMax, curVal)=> curMax > curVal? curMax: curVal)

    console.log(maxValue) // 10

 

四、高阶函数

柯里化技术,函数返回一个函数,核心是可以延时调用,如下可以化,其三层函数嵌套

    threeSum = a => b => c =>
        (a + b + c)

    sum = threeSum(1)(2)(3)
    console.log(sum) // 6

我们看这类函数很纠结,为什么写这么别扭,原因很简单,函数式编程,函数为王

我们前端有大量的数据来处理,一个很复杂的数据,我们可以通过函数组合的方式,一次性处理

这样,阅读起来很容易理解,你可以看看代码,这是很好容易阅读的,我们耐心做下去!!

    threeSum = a => b => c =>
        (a + b + c)

    sumFuncBaseThree = threeSum(1)(2)
    sum1 = sumFuncBaseThree(3)
    sum2 = sumFuncBaseThree(4)
    console.log(sum1) // 6
    console.log(sum2) // 7

  

 

标签:编程,console,name,title,JavaScript,log,数组,函数
From: https://www.cnblogs.com/qwe-asd-zxc-nm/p/17645710.html

相关文章

  • JavaScript中的数值
    JavaScript中的主要数值类型是Number类型,用于表示整数和近似的实数。JavaScript采用了由IEEE754标准定义的64位浮点格式来表示数值。这意味着JavaScript可以表示最大整数±1.7976931348623157×10^308和最小整数±5×10^-324。JavaScript中的这种数值格式允许我们准确......
  • 大数据技术Spark之RDD基础编程
    大数据技术Spark之RDD基础编程RDD(ResilientDistributedDataset)叫做弹性分布式数据集,是Spark中最基本的数据处理模型。代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。一、RDD的两种创建方式从集合(内存)中创建RDD从集合中创建RDD,Sp......
  • 2023.8.20 _码客行_编程公益课 在线评估
    2023.8.20_码客行_编程公益课在线评估师大附小六年级学生有\(400\)名学生参加期末测试,平均\(92\)分,其中男生的平均分为\(96\)分,女生的平均分为\(80\)分,参加竞赛的男生比女生多多少人?#include<iostream>usingnamespacestd;intmain(){cout<<"男生比女生多"<<200<<"......
  • Java网络编程:IO、NIO
    Socket套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。看不懂?别急,先回忆一下大学学的计算机网络。物理......
  • 8 JavaScript函数
    8JavaScript函数在JS中声明函数和python差不多.也要有一个关键字顶在前面.python是def,到了JS里换成了function,只不过在JS中没有像python那么死板,必须def后面必须跟上函数名.这也为我们未来做逆向提供了第一个超大的伏笔.//语法//声明函数function函数名(形参1,......
  • 荒原之梦考研数学原创:函数本体偏离点必为尖点
    荒原之梦原创:函数本体偏离点必为尖点:https://zhaokaifeng.com/16812/补充说明:前面所说的内容总结起来就是:一个处处可导的本体函数只有一个可导趋势,凡是已经有无数个点满足这个可导趋势的趋势(与本体函数重合)就必须继续满足该可导趋势(继续重合),否则,开始偏离本体函数可导趋势的点一......
  • java 网络编程
    网络编程一、概述网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。计算机网络把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大,功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件,软件,数据信息等资源。网......
  • devops之Python编程-类的基础架构
    Python中,可以通过关键字class来定义一个类。类是一种自定义数据类型,它可以包含属性(变量)和方法(函数)。下面是一个示例:classMyClass:def__init__(self,name):self.name=namedefsay_hello(self):print("Hello,"+self.name+"!")在上面的......
  • C++友元函数和友元类的使用
    1.友元介绍在C++中,友元(friend)是一种机制,允许某个类或函数访问其他类的私有成员。通过友元,可以授予其他类或函数对该类的私有成员的访问权限。友元关系在一些特定的情况下很有用,例如在类之间共享数据或实现特定的功能。友元可以分为两种类型:类友元和函数友元。2.类友元类友元(Friend......
  • C++友元函数和友元类的使用
    1.友元介绍在C++中,友元(friend)是一种机制,允许某个类或函数访问其他类的私有成员。通过友元,可以授予其他类或函数对该类的私有成员的访问权限。友元关系在一些特定的情况下很有用,例如在类之间共享数据或实现特定的功能。友元可以分为两种类型:类友元和函数友元。2.类友元类友元(Friend......