早期的Javascript不允许给函数表达式命名,因此你无法直接用函数表达式来写递归,例如一个阶乘函数:
function factorial(n) { return (!(n>1))? 1 : factorial(n-1)*n; } [1,2,3,4,5].map(factorial);
如果用表达式来写的话:
[1,2,3,4,5].map(function(n) { return (!(n>1))? 1 : /* what goes here? */ (n-1)*n; });
所以就需要 arguments.callee 了:
[1,2,3,4,5].map(function(n) { return (!(n>1))? 1 : arguments.callee(n-1)*n; });
但是这个解决方案并不好,在这种方式下用函数表达式实现尾递归十分困难,另一个主要问题是这样的递归调用会产生新的 this 引用:
var global = this; var sillyFunction = function (recursed) { if (!recursed) return arguments.callee(true); if (this !== global) alert("This is: " + this); else alert("This is the global"); } sillyFunction();
因此,ECMAScript3允许为函数表达式指定名字,以解决此问题:
[1,2,3,4,5].map(function factorial(n) { return (!(n>1))? 1 : factorial(n-1)*n; });
这样做有如下好处:
1、函数的调用方式更直观
2、不污染命名空间
3、this 的值保持不变
4、性能更好(访问 arguments 变量的消耗是很高的)
参考资料:
http://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in-javascript
https://developer.mozilla.org/en/JavaScript/Reference/functions_and_function_scope/arguments
http://en.wikipedia.org/wiki/JavaScript