读书笔记----javascript函数编程

<html>

<head>
    <meta charset="utf-8">
    <title>javascript函数编程</title>
    <meta name="keyword" content="javascript函数编程">
    <meta name="discription" content="javascript函数编程">
</head>

<body>
    <script>
    javascript函数编程

    第二章 一等公民的函数
    用一个函数把另外一个函数包起来, 目的仅仅是延迟执行, 真的是非常糟糕的编程习惯.

    第三章 纯函数的好处
    好处:
        1 纯函数是这样一种函数, 即相同的输入, 永远会得到相同的输出, 而却没有任何可观察的副作用;
    2 使用纯函数的形式, 函数就能做到自给自足;

    副作用:
        1 在计算结果的过程中, 系统状态的一种变化, 或者与外部世界进行的可观察的交互
    更新文件系统
    往数据库插入数据
    发送一个http请求
    可变数据
    打印 / log
    获取用户数据
    DOM查询
    访问系统状态


    追求 "纯"
    的理由
    1 可缓存性

    var memoize = function(f) {
        var cache = {};
        return function() {
            var arg_str = JSON.stringify(arguments);
            alert(arg_str);
            cache[arg_str] = cache[arg_str] || f.apply(f, arguments);
            return cache[arg_str];
        }
    }
    var squreNumber = memoize(function(x) {
        return x * x;
    })

    squreNumber(4); //16

    2 可移植性 / 自文档化

    3 可测试性

    4 合理性
    纯函数引用透明: 吐过一代代码可以替换成他执行所得的结果, 而且是在不改变整个程序行为的前提下替换的, 那么我们就说这段代码是引用透明的


    并行代码在服务端js环境以及使用了web worker的浏览器那里是非常容易实现的, 因为使用了线程(thread).
    不过出于对非纯函数复杂的奥绿, 当前主流观点还是避免使用这种并行

    slice(); //保留原数组不变
    splice(); //截取原数组,原数组改变



    第四章 柯里化 curry

    概念: 只传递函数一部分参数来调用它, 让他返回一个函数去处理剩下的参数.

    可以一次性的调用curry函数, 也可以每次只穿一个参数分多次调用


    function add(x, y) {
        return function(y) {
            return x + y;
        }
    }
    var a = add(1);
    a(2); //3

    只传给函数一部分参数通常也叫做局部调用, 能够大量减少样板文件的代码



    第五章 代码组合
    var compose = function(f, g) {
        return function(x) {
            return f(g(x));
        }
    }
    f, g都是函数, x式他们之间通过 "管道"
    传输的值.

    var toUpperCase = function(x) {
        return x.toUpperCase();
    }
    var exclain = function(x) {
        return x + "!";
    }

    var shout = compose(exclain, toUpperCase)

    shout("Hello");


    范畴学:
        是数学中的一个抽象分支, 能够形式化诸如集合论, 类型论, 群论, 以及逻辑学等数学分支中的一些概念.
    范畴学主要处理的对象, 态射和变化式.

    第六章 示例应用
    与命令式不同, 声明式意味着我们要写表达式, 而不是一步一步的指示

    //命令式
    var makes = [];
    for (i = 0; i < cars.length; i++) {
        makes.push(cars[i].make)
    }

    //声明式
    var makes = cars.map(function(car) {
        return car.make;
    })

    //命令式的循环要求你必须先实例化一个数组,而且执行完成这个实例化语句之后,解析器才继续执行后面的代码


    //命令式
    var authenticate = function(form) {
        var user = toUser(form);
        return login(user);
    }

    //声明式
    var authenticate = compose(login, touser);
    //虽然命令式的版本不一定就是错的,但是还是因编码了一种一步接着一步的执行方式.
    //而compose表达式只是简单的指出这么一个事实:用户验证是touser和login两个行为的
    //组合.这再次说明,声明式为代码更新提供了支持,是的我的应用代码成为了一种高级规范


    第七章 Hindley - Milner 类型签名

    类型签名补单可以用于编译时检测, 还是最好的文档.所以类型签名在函数式编程中扮演着非常重要的角色

    //strLength :: String ->Number
    var strLength = function(s) {
        return s.length;
    }

    //join:: String ->[String]->String

    var join = curry(fucntion(what, xs) {
        return xs.join(what);
    })


    第八章 特百惠

    函数式程序: 通过管道吧数据在一系列纯函数之间传递的程序.这些程就是声明式的行为规范

    var Container = function(x) {
        this.__value = x;
    }

    Container.of = function(x) {
        return new Container(x);
    }

    //Container 作为一个容器,Container.of作为构造器

    第九章 Monad
    pointed functor

    关于容器的of方法, 不是用老避免使用new关键字, 而是用来把值放到默认最小化上下文中的.of没有真的取代构造器
    他是一个我们称之为pointed的重要接口的一部分

    //这里关键是把任意的值丢到容器里然后开始导出使用map的能力

    IO.of("tetris").map(concat("master"));

    //IO("tetris master");

    Maybe.of(1336).map(add(1));
    //Map(1337);

    Task.of([{ id: 2 }, { id: 3 }]).map(_.prop("id"));

    //Task([2,3]);


    第十章 Applicative functor

    ap就是这样一种函数能够把一个functor的函数值应用到另一个functor的值上.
    Container.of(add(2)).ap(Container.of(3));
    Container(5);

    //all togrther now
    Container.of(2).map(add).ap(Container.of(3));
    //Container(5)


    //本例中的add是被map局部调用的,所以add必须是一个curry函数

    Container.prototype.ap = function(other_container) {
        return other_container.map(this.__value);
    }
    </script>
</body>

</html>

  总结:报告老板,在看懂之前我还能看{10,}遍

原文地址:https://www.cnblogs.com/SunlikeLWL/p/8681253.html