• 关于arguments对象以及函数的柯里化;


    1、arguments对象

    Arguments是个类似数组但不是数组的对象,说他类似数组是因为其具备数组相同的访问性质及方式,能够由arguments[n]来访问对应的单个参数的值,并拥有数组长度属性length。还有就是arguments对象存储的是实际 传递给函数的参数,而不局限于函数声明所定义的参数列表,而且不能显式创建 arguments 对象。在JavaScript中函数不介意传递进来多少参数,也不会因为参数不统一而错误。实际上,函数体内可以通过 arguments 对象来接收传递进来的参数。

    function box() {
        return arguments.length; //得到 6 
    }
    
    alert(box(1, 2, 3, 4, 5, 6));

    我们可以利用 length 这个属性, 来智能的判断有多少参数, 然后把参数进行合理的应用。 比如,要实现一个加法运算,将所有传进来的数字累加,而数字的个数又不确定。 

    function sum() {
        var sum = 0;
        if (arguments.length == 0) return sum; //如果没有参数,退出 
        for (var i = 0; i < arguments.length; i++) {
            sum += arguments[i]
        }
        return sum;
    }
    console.log(sum(1, 3, 5)) // 9

    arguments对象中有一个非常有用的属性:callee。arguments.callee返回此arguments对象所在的当前函数引用。在使用函数递归调用时推荐使用arguments.callee代替函数名本身。

    function count(a) {
        if (a == 0) return 1;
        return a + arguments.callee(--a);
    
    }
    var s = count(5)
    console.log(s); // 16 == >5+4+3+2+1+1

    2、柯里化

    在javascript中,函数可以接受多个参数,并且这些参数可以不固定(arguments),而柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

    通用实现:

    function currying(fn) {
        if (typeof fn !== 'function') throw new Error("currying():fn must be function");
        var args = [].slice.call(arguments, 1)
        return function() {
            var newArgs = args.concat([].slice.call(arguments))
            return fn.apply(null, newArgs)
        }
    }

    来看一个例子:

    function currying(fn) {
        //var args = Array.prototype.slice.call(arguments,1)
        if (typeof fn !== 'function') throw new Error("currying():fn must be function");
        var args = [].slice.call(arguments, 1);
        return function() {
            var newArgs = args.concat([].slice.call(arguments));
            return fn.apply(null, newArgs);
        }
    }
    var getPerson = currying(function() {
        var args = [].slice.call(arguments);
        console.log(args.toString());
    }, "jone")
    getPerson('jack', "tome", "eric")  // jone,jack,tome,eric
    getPerson('张三')                  // jone,张三

    思考题:已知fn为一个预定义函数,实现函数curryIt

    var fn = function(a, b, c) {
        return a + b + c
    };
    curryIt(fn)(1)(2)(3); //6
    
    function curryIt(fn) {
        //这里补充
    }

    可以试着玩一下,这里是用的函数的柯里化

    function curryIt(fn) {
        if (typeof fn !== 'function') throw new Error("curryIt():fn must be function");
        var args = [].slice.call(arguments, 1)
        return function() {
            args = args.concat([].slice.call(arguments));
            if (args.length < fn.length) {
                return arguments.callee;
            } else {
                return fn.apply(null, args)
            }
        }
    }

     参考:

    http://www.cnblogs.com/pigtail/p/3447660.html

    http://www.zhangxinxu.com/wordpress/2013/02/js-currying/

  • 相关阅读:
    开始写游戏 --- 第十一篇
    开始写游戏 --- 第十篇
    开始写游戏 --- 第九篇
    CDN的原理以及其中的一些技术
    深入理解Redis主键失效原理及实现机制
    使用 Redis 实现分布式系统轻量级协调技术
    Redis实现分布式锁
    进程线程协程
    类加载机制
    消息队列
  • 原文地址:https://www.cnblogs.com/jone-chen/p/5354309.html
Copyright © 2020-2023  润新知