arguments对象 的使用方法
有时候学的很散,那就只能随笔记录一下了。
1.Function的使用
首先介绍一下创建函数的三种方式:
下面聊聊Function的使用
Function这构造函数 可以用来新建函数对象
语法:
0. 一个参数都不传的情况, 创建的就是一个空的函数 如:var 函数名 = new Function()
1. 只传一个参数的情况,这个参数就是函数体 如:var 函数名 = new Function("函数体")
2. 传多个参数的情况,最后一个参数为函数体,前面的参数都是该函数的形参名
举个例子
创建一个计算两个数的和的函数
var sum = new Function("a", "b", "return a + b;");
console.log(sum(1, 1111));
如何解决使用Funciton创建函数时,代码过长的问题
1. 可以使用字符串拼接 让代码换行
2. 使用模板的方式,将代码写在模板标签内,获取该标签的内容
3. 使用反引号(` `) 引住字符串,那么就可以 换行了.
其中1,2方法有点麻烦,不利于代码简洁,所以我们就在下面 argunemnts对象的案例1 中可以看到 方法3 的使用。
2.arguments对象的用法
下面讲的虽然很全,但是这句话最实用:arguments是函数内部的一个对象 , 当函数调用的时候,系统会将所有传入的实参,依次存入这个数组对象。
其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数都会有一个Arguments对象实例arguments,它引用着函数的实参,可以用数组下标的方式"[]"引用arguments的元素。arguments.length为函数实参个数,arguments.callee引用函数自身。
arguments特性:arguments对象和Function是分不开的。因为arguments这个对象不能显式创建,arguments对象只有函数开始时才可用。
arguments使用方法:虽然arguments对象并不是一个数组,但是访问单个参数的方式与访问数组元素的方式相同
例如: arguments[0],arguments[1],。。。。。。。。arguments[n],
在js中 不需要明确指出参数名,就能访问它们。
1 函数内部的一个对象 arguments 2 当函数调用的时候,系统会将所有传入的实参,依次存入这个数组对象
// 要求允许函数调用时传入任意个数参数,
// 并且函数返回这些数字中最大的数字.
3 4 function max(){ 5 // console.log(arguments); 6 var maxNum = arguments[0]; 7 for (var i = 1; i < arguments.length; i++) { 8 maxNum = maxNum > arguments[i] ? maxNum :arguments[i]; 9 } 10 return maxNum; 11 } 12 13 console.log(max(1, 2, 34, 5, 6)); //34
检测参数个数 (arguments对象的length属性)
还可以用 arguments 对象检测函数的参数个数,引用属性 arguments.length 即可。
下面的代码将输出每次调用函数使用的参数个数:
1 function howManyArgs() { 2 alert(arguments.length); 3 } 4 5 howManyArgs("string", 45); 6 howManyArgs(); 7 howManyArgs(12); 8 上面这段代码将依次显示 "2"、"0" 和 "1"。
注释:与其他程序设计语言不同,ECMAScript 不会验证传递给函数的参数个数是否等于函数定义的参数个数。开发者定义的函数都可以接受任意个数的参数(根据 Netscape 的文档,最多可接受 255 个),而不会引发任何错误。任何遗漏的参数都会以 undefined 传递给函数,多余的函数将忽略。
arguments对象的callee属性
arguments对象有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数
下面是经典的阶乘函数(递归)
1 function factorial(num){ 2 if(num <=1){ 3 return 1; 4 }else{ 5 return num* factorial(num-1); 6 } 7 } 8 console.log(factorial(5));//120
但是,上面这个函数的执行与函数名紧紧耦合在了一起,可以使用arguments.callee可以消除函数解耦
1 function factorial(num){ 2 if(num <=1){ 3 return 1; 4 }else{ 5 return num* arguments.callee(num-1); 6 } 7 } 8 console.log(factorial(5));//120 9 但在严格模式下,访问这个属性会抛出TypeError错误 10 function factorial(num){ 11 'use strict'; 12 if(num <=1){ 13 return 1; 14 }else{ 15 return num* arguments.callee(num-1); 16 } 17 } 18 //TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them 19 console.log(factorial(5));
这时,可以使用具名的函数表达式
1 var factorial = function fn(num){ 2 if(num <=1){ 3 return 1; 4 }else{ 5 return num*fn(num-1); 6 } 7 }; 8 console.log(factorial(5));//120
好了,我们已经对 arguments对象了解的差不多了,下面介绍两个例子吧。
案例1 : 使用Function创建一个函数,给函数传入任意个数的参数,在函数内进行去重操作,然后返回去重后的数组.
1 //itar + tab 快速打出循环体 2 //new Function(``) 反引号里面写上函数体 3 4 var distinct = new Function(` 5 var arr = []; 6 for (var i = 0; i < arguments.length; i++) { 7 if(arr.indexOf(arguments[i])==-1){ 8 arr.push(arguments[i]); 9 } 10 } 11 return arr; 12 `); 13 14 console.log(distinct(1, 2, 34, 34, 5, 5)); // Array(4) [ 1, 2, 34, 5 ]
案例2:解析下面一行代码为什么会打印输出 2
1 var length=10; 2 function fn(){ 3 console.log(this.length); 4 } 5 var obj={ 6 length:5, 7 method:function(fn){ 8 arguments[0](); 9 } 10 } 11 fn(); // 10 12 obj.method(fn,1); // 2
代码先解析顺序,首先执行obj.method()方法,有两个参数,一个fn,一个1,这里的fn表示是一个参数,不是fn(). 此时已经执行method()方法了,那么就跳转到obj对象的method()里面去,从而执行arguments[0]()这句话,通过上面的知识点的学习,我们知道arguments[0] 就是函数 function(fn) 里面的参数 fn 。那么 arguments[0]() 也就是 fn() 。好,这时也就执行 fn() 这个方法,此时需要注意的是,fn() 方法中的this不是指向window,而是指向 arguments.
那么 arguments.length是多少呢?这里,arguments对象在methods方法里面,所以这里arguments包含methods方法里面两个参数,那么它的长度,arguments.length就是2