今天有空拿出《JavaScript高级程序设计》再仔细看了下,发现js这门语言真是灵活,可以说充满了黑魔法。
今儿给大伙讲js中黑魔法之一的类数组对象:
arguments
什么是arguments?
在js中,我们在调用有参数的函数时,当往这个调用的有参函数传参时,js会把所传的参数全部存储到一个叫arguments的实例对象里面。
类如:
function test(a,b,c,d,e,f){
console.log(arguments)
}
test(1,2,3,4,5,6)
在Chrome的控制台运行这段代码:
我们发现arguments的__proto__是Object,证明了arguments是个对象类型,并不是数组。它的属性名是按照传入参数的序列来的,第1个参数的属性名是”0″,第2个参数的属性名是”1″,以此类推,属性名类似数组中的索引值。
那么问题来了,arguments是怎么产生的呢?
Javascrip中每个函数都会有一个Arguments对象实例arguments,引用着函数的实参。它是寄生在js函数当中的,不能显式创建,arguments对象只有函数开始时才可用。
那么,既然arguments是一个对象,除了根据所在函数的实参动态生成的属性名之外,也会有其他的属性名。
比如:arguments.length为函数实参个数,arguments.callee表示引用函数自身。
js中的arguments是真的6
有了arguments这个对象之后,我们可以不用给函数预先设定形参了,可以动态地通过arguments为函数加入参数。这也说明JS这门语言是真的皮,并不会验证传递给函数的参数个数是否等于函数定义的参数个数,不像其他语言那样严谨。
function add() {
if( arguments.length == 2 ){
return arguments[0] + arguments[1];
}else{
return '传入参数不合法';
}
}
console.log( add(2,3) );
console.log( add(1,2,3) );
这在java中就得根据参数不同进行多次重载了,而js中没有重载机制,多个同名不同参的函数,最js文档最下面的那个函数给直接覆盖。
所以,面对同名不同参的情况,我们可以利用arguments对参数进行判断,从而进行不同的运算。
arguments的属性介绍
arguments.length就不用多讲了,指的是函数传入实参的个数。
arguments.callee是指向当前正在执行函数的指针(引用),直白点来说,就是这个属性值就是当前函数的代码。
function add() {
var a =2;
var b = 3;
var c = a+b;
console.log(arguments.callee);
console.log(c)
}
add()
arguments.callee的使用
在《js高级程序设计》的递归章节中,有这样的一段示例代码:
function factorial (num) {
if (num <= 1){
return 1;
} else {
return num * factorial(num-1);
}
}
arguments.callee可以实现对函数的递归使用,上述的代码可以写成这样:
function factorial (num) {
if (num <= 1){
return 1;
} else {
return num * arguments.callee(num-1);
}
}
通过使用arguments.callee代替函数名,可以确保无论怎么样调用函数都不会出现问题。因此,在编写递归时,使用arguments.callee总比使用函数名更保险。 ——《js高程》原话
这里又出现了一个问题,怎么说使用函数名不保险呢?
当函数出现这样的调用时,
var anfactorial = factorial;
factorial = null;
console.log(anfactorial(4))
第一种情况会出现报错:
第二种用arguments.callee代替函数名,正常执行:
但是在ES4中新增的严格模式中,arguments.callee这个属性会导致错误。可能自己人都看不惯js这么皮了,限制了一下。在没有使用严格模式的情况下,可以使用。对外封装开源的小插件,不建议用callee属性,但是arguments是基本都会用到的。
arguments真是一个好东西。
本文参考了《JavaScript高级程序设计》js中arguments的用法:
[]
js的arguments到底是什么:[]
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: lzxmw777