callee其实是arguments的一个方法,用于指向当前执行的函数,通过这个属性我就可以做到在函数体内部调用当前函数,也就是传说中的递归,通常是在匿名函数或者不知道当前函数名称的情况下使用。
//一个简单的阶乘例子
function factorial (n) {
return !(n > 1) ? 1 : factorial(n - 1) * n;
}
[1, 2, 3, 4, 5].map(factorial);
// 如果我们采用匿名函数,就需要用到callee了
[1, 2, 3, 4, 5].map(function(n) {
return !(n > 1) ? 1: arguments.callee(n - 1) * n;
});
callee其实是js早期的设计,在ECMAScript5提出的严格模式下,已经禁止使用arguments.callee()。
caller是function的一个方法,用于指向调用当前函数的函数,它的作用是可以查看函数的调用栈,如果是最上层的函数,它的caller会返回null;
//一个简单的函数调用例子
function f(n) { g(n - 1); }
function g(n) { if (n > 0) { f(n); } else { stop(); } }
f(2);
我们可以看到函数调用的顺序为: f(2) => g(1) => f(1) => g(0) => stop() 因此下面的表达式会返回true;
stop.caller === g && f.caller === g && g.caller === f
因此我们在stop函数中查看他的调用栈:
var f = stop;
var stack = 'Stack trace:';
while (f) {
stack += '\n' + f.name;
f = f.caller;
}
在ECMAScript5的严格模式下,已经禁止使用caller方法了。