zoukankan      html  css  js  c++  java
  • Currying and Uncurrying Js

    //反科里化
    Function.prototype.uncurrying = function() {
    var _this = this;
    return function() {
    return Function.prototype.call.apply(_this, arguments);
    //_this.call(arguments);
    //在下面的例子中Array.prototype.push == _this
    //因为call 本身也是个函数
    //Function.prototype.call.apply 就是去调用call()方法
    //也就是Array.prototype.push.call(arguments);
    //arguments 也就是 return function()中传入的参数组
    //例子中push(arr,"a") arguments 就是[arr,"a"];
    //apply第二个参数接受数组,arguments 是伪数组(Object 类型).
    //call 接受参数序列 arg1, arg2, , argN ,arguments 会被转化成 arr , "a"
    //所以实际上到最后我们得到的是
    //Array.prototype.push.call(arr , "a");
    //即 arr.push("a")
    };
    };


    var arr = new Array();
    Array.prototype.push.call(arr, "a"); //arr == ["a"]


    var push = Array.prototype.push.uncurrying();
    var arr = new Array();
    push(arr, "a"); //arr == ["a"]
    push(arr, "b"); //arr == ["a","b"]

     

    var toUpperCase = String.prototype.toUpperCase.uncurrying();
    var arr1 = arr.map(function(elem) {
    return toUpperCase(elem); //map()迭代数组元素 A ,B,并把结果放在一个新数组中返回
    })

    console.log(arr1); //["A", "B"]

    var arr2 = arr.forEach(function(elem, index) {
    return toUpperCase(index + "." + elem);//foreach()只迭代数组元素,没有返回值 1.a 2.b
    })

    console.log(arr2); //undefined

     


    var selfindexof = function() {

    var ary = Array.prototype.shift.call(arguments);
    return Array.prototype.indexOf.apply(ary, arguments);
    //等价于 return Function.prototype.call.apply(Array.prototype.indexOf,arguments);

    }

    console.log(selfindexof(arr, "b"));// 1

     


    var add_fn = function(obj, fn_keys) {
    for (var i = 0, fn; fn = fn_keys[i++];) {~
    ~function(fn) {
    var new_fn = Array.prototype[fn].uncurrying();
    obj[fn] = function() {
    new_fn.apply(this, [this].concat(Array.prototype.slice.call(arguments)));
    //arguments是Object,Array.prototype.slice.call(arguments)将arguments转化成数组
    //如果不转化concat之后得到的是[this,Object]
    //转化之后concat之后得到的是[this,arguments[0],arguments[1]...]

    return this;
    };
    }(fn)
    }
    }

    var A = function() {

    }

    add_fn(A.prototype, ['push', 'indexOf', 'shift', 'pop', 'forEach']);

    var a = new A;


    console.log(a.push)
    a.push(4).push(5).push(6).forEach(function(n, i) {
    // alert(n);
    })


    /*科里化*/
    Function.prototype.currying = function(){
    //形成了闭包,所以_args会常驻内存中,因为闭包依赖于外部函数的变量
    var _args = [];
    var _this = this;
    return function(){
    if (arguments.length === 0) {
    return _this.apply(this,_args);
    }
    [].push.apply(_args, arguments);
    return arguments.callee;
    }
    }


    //实现惰性计算
    var monthly_cost = 0;

    var monthly_cost_fn = function() {
    for (var i = 0, c; c = arguments[i++];) {
    monthly_cost += c;
    }
    return monthly_cost;
    }.currying();

    /*此时的monthly_cost_fn = function(){
    if (arguments.length === 0) {
    return _this.apply(this,_args);
    }
    [].push.apply(_args, arguments);
    return arguments.callee;
    }*/

     

    monthly_cost_fn(100);
    monthly_cost_fn(200);//有参数不会去计算,而是把参数存贮起来
    monthly_cost_fn(300);

    console.log(monthly_cost_fn.call());//参数为0,会去执行计算,得出600

  • 相关阅读:
    使用 linux kernel +busybox 定制linux系统
    记一次golang的内存泄露
    关于Queries_per_sec 性能计数器
    NUMA导致的MySQL服务器SWAP问题分析
    Drop Table对MySQL的性能影响分析
    当MySQL数据库遇到Syn Flooding
    tcp_tw_recycle参数引发的数据库连接异常
    一例数据同步异常问题分析
    MySQL大量线程处于Opening tables的问题分析
    MySQL DeadLock故障排查过程
  • 原文地址:https://www.cnblogs.com/mguo/p/3143852.html
Copyright © 2011-2022 走看看