今天有空拿出《JavaScript高级程序设计》再仔细看了下,发现js这门语言真是灵活,可以说充满了黑魔法。

arguments.callee_callee_arguments.callee

今儿给大伙讲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的控制台运行这段代码:

callee_arguments.callee_arguments.callee

我们发现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) );

arguments.callee_arguments.callee_callee

这在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_arguments.callee_callee

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_callee_arguments.callee

第二种用arguments.callee代替函数名,正常执行:

callee_arguments.callee_arguments.callee

但是在ES4中新增的严格模式中,arguments.callee这个属性会导致错误。可能自己人都看不惯js这么皮了,限制了一下。在没有使用严格模式的情况下,可以使用。对外封装开源的小插件,不建议用callee属性,但是arguments是基本都会用到的。

arguments真是一个好东西。

本文参考了《JavaScript高级程序设计》js中arguments的用法:

[]

js的arguments到底是什么:[]

限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: lzxmw777

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注