在JavaScript的函数内部,有一个特殊的对象,那便是arguments,它是一个类数组对象(arguments对象只是与数组类似,它并不是Array的实例),包含着传入函数中的所有参数,下面看一个简单的例子。
function f() {
for(var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
f(1,"string",true); // 以下注释为函数执行结果
/*
1
string
true
*/
我们可以明显的看出,arguments对象中保存着传递给函数的每一个参数,并且可以通过方括号语法来访问对应的参数,同时arguments对象的length属性保存了传递给函数的参数的数量,因此可以简单的遍历访问传递给函数的参数。
arguments对象除了length属性之外,还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数,可能有点绕,不过看一下下面这个例子就明白了。
function factorial(num) {
if(num <= 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
function factorial_callee(num) {
if(num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
// 以下注释为函数执行结果
factorial(5); // 120
factorial_callee(5); // 120
上述两个函数均通过递归的方式实现阶乘的功能,第一个函数通过函数名调用自己,第二个函数则通过arguments.callee调用自己,相信从中可以看出arguments.callee相当于arguments对象所属函数的函数名。
JavaScript的函数里还定义了另外一个属性:caller,这个属性中保存着调用当前函数的函数的引用,即指向调用当前函数的函数的指针,如果是在全局作用域中调用当前函数,则它的值为null,同样,我们通过一个例子来了解它是如何工作的。
function f() {
console.log(f.caller);
}
// 以下注释为函数执行结果
f();
// null
function outer() {
console.log("outer");
inner();
}
function inner() {
console.log("inner");
console.log(inner.caller);
}
// 以下注释为函数执行结果
outer();
/*
outer
inner
outer() {
console.log("outer");
inner();
}
*/
第一个是在全局作用域中调用 f 函数,因此 f.caller 的值为 null;第二个是在 outer 函数中调用 inner 函数,因此 inner.caller 是指向 outer 的指针。
在ECMAScript 5 中还定义了arguments.caller属性,不过在非严格模式下这个属性始终是undefined。另外,在严格模式下,访问arguments.callee和arguments.caller都会导致错误。
以上便是关于JavaScript函数内部属性arguments.callee、arguments.caller、caller的简单介绍,至于如何使用好这些属性进而发挥其独特的作用,就需要读者发挥自己的聪明才智了。
水平有限,如有错误,还请批评指正。