关于Javascript中arguments的个人理解

Javascript 的函数中有个名为 arguments 的类数组对象。它看起来是那么的诡异而且名不经传,但众多的 Javascript 库都使用着它强大的功能。所以,它的特性需要每个 Javascript 程序员去熟悉它。

1 重载,我们应用arguments就是满足函数的重载(即多态),值得指出的是他存储的不是在函数声明中的参数,而是直接存储函数中的参数。
argument:类数组对象,该对象有三个属性
(1)获取参数值  argument[0],argument[1].... ...
(2)获取参数的长度 argument.length
(3)获取当前执行函数 argument.callee,实现递归调用(详见参看函数->递归函数)
以上说明的举例说明:
实现:一个参数的时候输出该值,两个参数的时候输出两个参数的和
<script>
    function add()
    {
        if(arguments.length==1)
        {
            return arguments[0];
        }
        else if(arguments.length==2)
        {
            return arguments[0]+arguments[1];
        }    
    }
    alert(add(10));
    alert(add(10,10));
</script>


2 转换成实际数组:由于语言设计的错误,导致这个argument类数组对象只有以上两种属性,缺少了所有的数字方法,为了弥补这种缺陷,我们需要把argument对象转化成真正的数组,我们可以用数组的slice方法+构造函数伪装完成(具体为啥用slice,我也不知道,请大牛指点,如果用别的数组方法是不行的)

    var args=Array.prototype.slice.call(arguments);
            数组对象args包含了所有arguments对象包含的值。
 
3 函数中的应用
应用领域:参数构造函数(或叫套用(精粹叫法),分布应用(精编叫法))
大体思路是将函数与传递给它的参数相结合返回一个新的匿名函数
大体思路是:
function makeFunc()
{
var args=Array.prototype.slice.call(arguments);//获取makeFunc的参数
var func=args.shift();//移出调用函数
return function()
{
return func.apply(null,args.concat(Array.prototype.slice.call(arguments)));
                                //参数合并成数组,并执行传入func调用
}
}

举例:操作参数求和。。。

<script>
function add()
{
    var sum=0;
    for(var i=0;i<arguments.length;i++)
    {
        sum+=arguments[i];
    }
    return sum;
}
    function makeFunc()
    {
        var args=Array.prototype.slice.call(arguments);
        var func=args.shift();
        return function()
        {
            return func.apply(null,args.concat(Array.prototype.slice.call(arguments)));
        }
    }
    var a=makeFunc(add,1,2,3);
    alert(a(4,5))//输出15
</script>

举例:输出函数参数加1

 
<script>
var op={
    "+":function(a,b){return a+b;},
    "*":function (a,b){return a*b},
    "==":function (a,b){return a==b},
    "===":function(a,b){return a===b}//等等吧
}
    function partial()
    {
        var fnSlice=Array.prototype.slice;
        var knownArgs=fnSlice.apply(arguments);//主要是存放要加的那个1,但也获取了函数即op["+"]),
        var func=knownArgs.shift();//把获取的op["+"]移给func,这样knownArgs就剩下数组1了
        return function()
        {
            var realArgs=[];            
            var realArgs=knownArgs.concat(Array.prototype.slice.apply(arguments))//这时候括号内的数组中遍历出的元素,让之前存放那个1和这个新存放的元素整合为一个新的数组。
            return func.apply(null,realArgs);//执行op["+"]
        }
    }
    function forEach(arr,fn)
    {
        for(var i=0;i<arr.length;i++)
        {
            fn(arr[i]);
        }        
    }
    function map(fn,arr)
    {
        var result=[];
        forEach(arr,function(element){
            result.push(fn(element))//fn就是匿名函数,循环进值
        })
        return result;
    }
    var a=map(partial(op["+"],1),[1,2,3,4]);
    forEach(a,function(element){
            document.write(element);
    })
</script>

 

方法二,用循环方法也可以
<script>
var op={
    "+":function(a,b){return a+b;},
    "*":function (a,b){return a*b},
    "==":function (a,b){return a==b},
    "===":function(a,b){return a===b}//等等吧
}
    function partial(func)
    {
        var knownArgs=arguments;
        return function()
        {
            var realArgs=[];            
            for(var i=1;i<knownArgs.length;i++)//由于func是函数,所以从1开始遍历
            {
            realArgs.push(knownArgs[i]);
            }
            for(var i=0;i<arguments.length;i++)
            {
                realArgs.push(arguments[i]);
            }
            return func.apply(null,realArgs);
        }
    }
    function forEach(arr,fn)
    {
        for(var i=0;i<arr.length;i++)
        {
            fn(arr[i]);
        }        
    }
    function map(fn,arr)
    {
        var result=[];
        forEach(arr,function(element){
            result.push(fn(element))
        })
        return result;
    }
    var a=map(partial(op["+"],1),[1,2,3]);
    forEach(a,function(element){
            document.write(element);
    })
</script>


当然你看不惯shift,用slice也可以,但是记住func传进呀

 
<script>
var op={
    "+":function(a,b){return a+b;},
    "*":function (a,b){return a*b},
    "==":function (a,b){return a==b},
    "===":function(a,b){return a===b}//等等吧
}
    function partial(func)
    {
        var fnSlice=Array.prototype.slice;
        var knownArgs=fnSlice.apply(arguments);//主要是存放要加的那个1,但也获取了传入的函数func(即op["+"]),所有后面我们会用slice(1)方法去掉它
        return function()
        {
            var realArgs=[];
            var realArgs=knownArgs.slice(1).concat(Array.prototype.slice.apply(arguments))//这时候括号内的数组中遍历出的元素,让之前存放那个1和这个新存放的元素整合为一个新的数组。
            return func.apply(null,realArgs);
        }
    }
    function forEach(arr,fn)
    {
        for(var i=0;i<arr.length;i++)
        {
            fn(arr[i]);
        }        
    }
    function map(fn,arr)
    {
        var result=[];
        forEach(arr,function(element){
            result.push(fn(element))
        })
        return result;
    }
    var a=map(partial(op["+"],1),[1,2,3,4]);
    forEach(a,function(element){
            document.write(element);
    })
</script>

 

 
posted @ 2013-04-29 23:40  riselee  阅读(195)  评论(0)    收藏  举报