arguments.callee
函数内, 有两个特殊对象: arguments 和 this
arguments 的主要用途, 是保存函数参数,默认包含所有传入函数内的参数,但这个对象还有属性,名为callee,callee是一个指针,指向该arguments对象所在的函数,因此:
因此,经典阶乘函数:
function fn(num){
if(num <= 1) {return 1
}
return num * fn(num-1)
}
也可以这么写:
function fn(num){
if(num<=1){
return 1
}
return num * arguments.callee(num-1)
}
那为啥要这么写?在函数有名字并且函数名不会改变时,这么写没有必要,只是函数的执行与函数名耦合到了一起,为了解耦合,才使用arguments.callee() 的写法,如下:
var fn2 = fn; // fn引用上面的方法
fn2(3) // 6
fn = function(){return 0} // 重写fn 方法
fn2(3) // 6 // fn2依然返回预期的结果
fn(3)// 0 // fn 被重写
fn创建了一个递归对象,fn2引用了该对象, 给fn重新赋值的时候,相当于开辟了新内存改变了fn的指针,此时fn2依然指向递归对象,因此结果如上。
但arguments.callee() 现在弃用了,原因: arguments是一个很大的对象,不仅仅只有我们看到的这样,每次递归调用时都要重新创建该对象,因此操作arguments很消耗浏览器性能。
argumetns是弃用了,但是如果还想用上面的写法,那么。。。。
function fn(num){
return (function infn(num){
if(num <=1){
return 1
}
return num * infn(num-1)
})(num)
}
hhhhhhhhhhhhhhhhh, 就是用一个函数把递归包一下。。。。。好像不是什么很好的方案,但实用,这样也能实现解耦合的目的。
网友评论