1.1.1函数式编程

Posted HeiYanjing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.1.1函数式编程相关的知识,希望对你有一定的参考价值。

概念引入

面向对象编程的思维方式:把现实世界中的事物抽象成程序世界中的类和对象,通过封装、继承和多态来演示事物事件的联系
函数式编程的思维方式:把现实世界的事物和事物之间的联系抽象到程序世界(对运算过程进行抽象)

高阶函数 (Higher-order function),可以把函数作为参数传递给另一个函数,可以把函数作为另一个函数的返回结果。
使用高阶函数的意义:
抽象可以帮我们屏蔽细节,只需要关注与我们的目标
高阶函数是用来抽象通用的问题
作为参数传递:

function forEach (arr,fn) {
    for(let i =0;i<arr.length;++i){
        fn(arr[i]);
    }
}

function filter(arr,fn){
    let result = [];
    for(let i =0;i<arr.length;++i){
        if(fn(arr[i])){
            result.push(arr[i])
        }
    }
    return result;
}

const map = (arr, fn) => {
    let result = [];
    for (let val of arr) {
        result.push(fn(val))
    }
    return result;
}

const every = (arr, fn) => {
    let flag = true;
    for(let val of arr){
        flag = fn(val);
        if(!flag){
            break;
        } 
    }
    return flag;
}

recude的实现复杂一些,也是一个常见的面试题。
recude的作用及特征:
接收两个参数,第一个参数是在每一项上调用的函数
该函数接收 4 个参数:
前一个值 prev
当前值 cur
项的索引 index
数组对象 array
第二个可选参数是作为归并基础的初始值

arr.reduce(function(prev, cur, index, arr){}, initialValue)

递归法实现

Array.prototype.myreduce = (fn, initialVal) {
     // 基本类型判断
    if (typeof fn !== "function") {
        throw new TypeError("arguments[0] is not a function");
    }
    let acc = initialVal || this[0];
    const initIndex = initialVal ? 0 : 1;
    for (let i = initIndex; i < this.length; ++i) {
        acc = fn(acc, this[i], i, this);
    }
    return acc;
}

作为返回值

function once(fn){
    let done = false;
    return function() {
        if(!done){
            done = true;
            return fn.apply(this,arguments);
        }
    }
}
let pay = once(function (money){
    console.log(`pay ${mondy} RMB`);
});

// 只付一次
pay(5);
pay(5);
pay(5);

闭包
闭包 (Closure):函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包。
可以在另一个作用域中调用一个函数的内部函数并访问到该函数的作用域中的成员。
闭包的本质:函数在执行的时候会放到一个执行栈上当函数执行完毕之后会从执行栈上移除,但是堆上的作用域成员因为被外部引用不能释放,因此内部函数依然可以访问外部函数的成员。

纯函数:相同的输入永远得到相同的输出
一个纯函数与不纯函数的例子
数组的 slice 和 splice 分别是:纯函数和不纯的函数
slice返回数组中指定部分,不会修改原数组,splice对数组进行操作返回该数组,会改变原数组。
纯函数好处
可缓存,因为纯函数对相同的输入始终有相同的结果,所以可以把纯函数的结果缓存起来,比如一个计算圆面积的方法,只用输入半径,就能获取圆面积。
可测试,纯函数让测试更方便
并行处理,在多线程环境下并行操作共享的内存数据很可能会出现意外情况
纯函数不需要访问共享的内存数据,所以在并行环境下可以任意运行纯函数 (Web Worker)

副作用
副作用让一个函数变的不纯,纯函数的根据相同的输入返回相同的输出,如果函数依赖于外部的状态就无法保证输出相同,就会带来副作用。
所有的外部交互都有可能带来副作用(配置文件,数据库,获取用户输入),副作用也使得方法通用性下降不适合扩展和可重用性,同时副作用会给程序中带来安全隐患给程序带来不确定性,但是副作用不可能完全禁止,尽可能控制它们在可控范围内发生。

举个例子

// 不纯的
let mini = 18;
function checkAge (age) {
  return age >= mini;
} 
// 纯函数
function checkAge (age) {
  let mini = 18;
  return age >= mini;
}

以上是关于1.1.1函数式编程的主要内容,如果未能解决你的问题,请参考以下文章

《On Java 8》中文版 第十三章 函数式编程

web代码片段

html 将以编程方式附加外部脚本文件的javascript代码片段,并按顺序排列。用于响应式网站,其中ma

Python函数式编程,范围和变量。我哪里错了?

36 函数式编程

前端必学——函数式编程