先举例:数组
function factorial(num) { if (num <= 1) { return num; } else { return num * factorial(num-1); } } //输出120
//进一步去思考
有名字的函数,且名字不会有变化的状况下,这样定义没有问题。
若名字有变化呢,这里就须要考虑到 须要 【消除】 这种 【紧密耦合】
function factorial(num)
{
if(num<=1)
{
return 1;
}
else{
return num * arguments.callee(num-1);
}
}
//使用 arguments.callee来解决 注释:argument是一个很大的对象,每次调用都须要从新建立 会影响浏览器的性能 还会影响 闭包
咱们知道arguments.callee是一个指向正在执行的函数的指针 (若不理解arguments能够看下面的)浏览器
function factorial(num) { if (num <= 1) { return 1; } else { return num * arguments.callee(num - 1); } } var trueFactorial = factorial; alert(trueFactorial(5)); //120
//注释:能够在此处 中 的浏览器调试 看 factorial对象 factorial = function () { return 0; }
//注释:能够在此处中 的浏览器调试 看 trueFactorial 和 factorial对象 alert(trueFactorial(5));// 120 若是没有使用arguments.callee,将返回0 function mm() { alert(factorial(5)); //0 alert(trueFactorial(5));//120 }
思考:arguments.callee指向arguments对象的拥有函数引用,当把factorial函数的引用赋给trueFactorial后,arguments对象的拥有函数变成了tureFactorial
什么是arguments ?闭包
arguments是类数组对象,和数组有不少共性。函数
function showargs(){
console.log(arguments)
}
showargs(1,2,3,4);
//获得的结果如图
从图片来看
arguments对象的 ==proto==是指向的object,说明了是一个类数组对象
ES4添加了严格模式,在严格模式中禁止不使用var来直接声明一个全局变量,并且arguments也被禁用了性能
回到正题,上面讲述了递归时的解耦,经过使用arguments.callee来解决,可是在严格模式下是不能访问arguments.callee,那此时有没有解决方案呢?spa
//能够经过命名函数表达式来达成相同的结果 var factorial=(function f(num){ if(num<=1){ return 1; } else { return num* f(num-1) } })