1.函数组合 ->饲养函数:compose

若干个纯函数、偏函数、柯里化函数组合成一个新的函数、形成数据传递、并实现一种有序执行的效果

demo1

  1. function toUpperCase(str) {
  2. return str.toUpperCase();
  3. }
  4. function exclaim(str) {
  5. return str + '!';
  6. }
  7. function compose(f, g) {
  8. return function (x) {
  9. return f(g(x));//左倾: 函数自右向左执行
  10. }
  11. }
  12. var f = compose(exclaim, toUpperCase);
  13. console.log(f);
  14. console.log(f('hello'));
  15. console.log(exclaim(toUpperCase('hello')));

image.png
//x是通过f,g之间的“管道”传输值

demo2 函数组合自定义长度

写法一

        function toUpperCase(str) {
            return str.toUpperCase();
        }
        function exclaim(str) {
            return str + '!';
        }
        function split(arr) {
            return arr.split('');
        }
        function reverse(arr) {
            return arr.reverse();
        }
        function join(arr) {
            return arr.join('-');
        }
        function compose(f, g) {
            return function (x) {
                return f(g(x));//左倾: 函数自右向左执行
            }
        }
        function compose1() {
            console.log(arguments);
            //  Array.prototype.slice.call 类数组转数组
            var args = Array.prototype.slice.call(arguments),
                len = args.length - 1;
            console.log(args);
            // arguments.length - 1 最后一个形参
            return function (x) {
                // res:保存并执行第一个要执行的函数 将返回值保存进res
                var res = args[len](x);
                while (len--) {
                    res = args[len](res)
                }
                return res;
            }
        }
        var f = compose1(join, reverse, split, exclaim, toUpperCase);
        console.log(f('hello'));

image.png
image.png

写法二

           function toUpperCase(str) {
            return str.toUpperCase();
        }
        function exclaim(str) {
            return str + '!';
        }
        function split(arr) {
            return arr.split('');
        }
        function reverse(arr) {
            return arr.reverse();
        }
        function join(arr) {
            return arr.join('-');
        }
                function compose2() {
            var args = Array.prototype.slice.call(arguments);
            return function (x) {
                return args.reduceRight(function (prev, cur) {
                    return cur(prev);
                }, x);
            }
        }
        var f = compose2(join, reverse, split, exclaim, toUpperCase);
        console.log(f('hello'));

image.png

多种调用形式

        function toUpperCase(str) {
            return str.toUpperCase();
        }
        function exclaim(str) {
            return str + '!';
        }
        function split(arr) {
            return arr.split('');
        }
        function reverse(arr) {
            return arr.reverse();
        }
        function join(arr) {
            return arr.join('-');
        }
        function compose(f, g) {
            return function (x) {
                return f(g(x));//左倾: 函数自右向左执行
            }
        }
        function compose1() {
            // console.log(arguments);
            //  Array.prototype.slice.call 类数组转数组
            var args = Array.prototype.slice.call(arguments),
                len = args.length - 1;
            // console.log(args);
            // arguments.length - 1 最后一个形参
            return function (x) {
                // res:保存并执行第一个要执行的函数 将返回值保存进res
                var res = args[len](x);
                while (len--) {
                    res = args[len](res)
                }
                return res;
            }
        }
        function compose2() {
            var args = Array.prototype.slice.call(arguments);
            return function (x) {
                return args.reduceRight(function (prev, cur) {
                    return cur(prev);
                }, x);
            }
        }
        var f = compose2(join, reverse, split, exclaim, toUpperCase);
        var f1 = compose1(compose1(join, reverse), split, exclaim, toUpperCase);
        var f2 = compose2(compose2(join, reverse), split, exclaim, toUpperCase);

        console.log(f('hello'));
        console.log(f1('hello'));
        console.log(f2('hello'));

image.png

实战 查找课时大于20 免费的课程

    <div id="J_data" style="display: none;">
        [{"id":"1","course":"前端开发之企业级深度JavaScript特训课【JS++前端】","classes":"19","teacher":"小野","img":"1.jpg","is_free":"1","datetime":"1540454477","price":"0","hours":"18"},
        {"id":"2","course":"WEB前端工程师就业班之深度JSDOM+讲师辅导-第3期【JS++前端】","classes":"22","teacher":"小野","img":"2.jpg","is_free":"1","datetime":"1540454477","price":"699","hours":"16"},
        {"id":"3","course":"前端开发之企业级深度HTML特训课【JS++前端】","classes":"3","teacher":"小野","img":"3.jpg","is_free":"1","datetime":"1540454477","price":"0","hours":"12"},
        {"id":"4","course":"前端开发之企业级深度CSS特训课【JS++前端】","classes":"5","teacher":"小野","img":"4.jpg","is_free":"1","datetime":"1540454477","price":"0","hours":"13"},
        {"id":"5","course":"前端就业班VueJS+去哪儿网+源码课+讲师辅导-第3期【JS++前端】","classes":"50","teacher":"哈默","img":"5.jpg","is_free":"0","datetime":"1540454477","price":"1280","hours":"11"},
        {"id":"6","course":"前端就业班ReactJS+新闻头条实战+讲师辅导-第3期【JS++前端】","classes":"21","teacher":"托尼","img":"6.jpg","is_free":"1","datetime":"1540454477","price":"2180","hours":"13"},
        {"id":"7","course":"WEB前端开发工程师就业班-直播/录播+就业辅导-第3期【JS++前端】","classes":"700","teacher":"JS++名师团","img":"7.jpg","is_free":"0","datetime":"1540454477","price":"4980","hours":"19"}]
    </div>

                var data = JSON.parse(document.getElementById('J_data').innerHTML);
        // console.log(data);
        function classesFilter(data) {
            return data.classes > 20 && data;
        }
        function freeFilter(data) {
            return data.is_free === '1' && data;
        }
        var arr = [];

        data.forEach(function (val) {
            var f = compose2(freeFilter, classesFilter);

            f(val) && arr.push(f(val));
        });
        console.log(arr);