JavaScript函数内部属性:arguments.callee、arguments.caller、caller

在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的简单介绍,至于如何使用好这些属性进而发挥其独特的作用,就需要读者发挥自己的聪明才智了。

水平有限,如有错误,还请批评指正。

你可能感兴趣的:(前端)