关于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>
浙公网安备 33010602011771号