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

  • 相关阅读:
    LeetCode(35):Palindrome Number 分类: leetCode 2015-07-10 09:26 161人阅读 评论(0) 收藏
    在pycharm进行单元测试(unittest python)
    Django 基本操作
    Django中数据库操作相关的错误
    Question&&Answer
    ubuntu下 SVN 服务器搭建及使用
    python 在不同层级目录import 模块的方法
    Ubuntu 16.04安装PyCharm
    修改mysql中数据库存储主路径
    查看mysql的数据库物理存放位置
  • 原文地址:https://www.cnblogs.com/mguo/p/3143852.html
Copyright © 2011-2022 走看看