代码
- function Y(le) {
- return function (f) {
- return f(f);
- }(function (f) {
- return le(function (x) {
- return f(f)(x);
- });
- });
- }
- var factorial = Y(function (fac) {
- return function (n) {
- return n <= 2 ? n : n * fac(n - 1);
- };
- });
-
- var number120 = factorial(5);
简单的递归函数,其实和
代码
- >>> function t(n){return n <= 2 ? n : n * t(n - 1);}
- >>> t(5)
- 120
是一个道理,可是为什么要这么写呢,就是因为要彻底的实现匿名函数,首先函数Y里面必须定义个递归函数名,比如fac,其次参数函数比如主动返回真实函数,如
代码
- function (n) {
- return n <= 2 ? n : n * fac(n - 1);
- };
可是怎么把这个奇怪的返回参数的引用弄到fac上面呢,这个就比较费劲了为什么这么说呢,因为在传递参数那一刻已经生成了
代码
- function (fac) {
- return function (n) {
- return n <= 2 ? n : n * fac(n - 1);
- };
- }
这么一个函数,所以内部return的函数所有的scope chain都确定了,不能在把fac的引用通过scope修改为自身了,那就只有一个办法,就是想办法,把这个内部返回的参数当作参数函数的参数传近来,那这样可以吗
代码
- function Y(tmp){
- return tmp(tmp());
- }
这样可以吗测试一下factorial(3)返回了6但是factorial(5)却显示fac未定义,为什么呢,其实事实上我们只给第一个参数函数传递了fac参数函数。而fac参数函数内部却没有fac参数函数的引用了,也就是说3会走3*2,而2不需要再走fac了,所以结果正确,但是5*4,4还必须走fac所以就发生fac丢失的问题,那如何处理,我写了函数
代码
- function Y(tmp) {
- eval(tmp().toString().replace("function ", "function fac"));
- return fac;
- }
这个函数什么意思,就是先执行参数函数,然后把函数文本篡改下,加上fac的名字,在eval声明下,最后返回fac自己的引用,而这个引用由于scope chain的作用,当然可以找到fac自己的引用了,再说最开头的函数
代码
- function Y(le) {
- return function (f) {
- return f(f);
- }(function (f) {
- return le(function (x) {
- return f(f)(x);
- });
- });
- }
其实大同小异f(f)永远返回le运行的结果,也就是实际函数,而实际函数闭包当中的fac也就是
代码
- function (x) {
- return f(f)(x);
- }
这个函数又去调用闭包当中的f,而f(f)自然返回带有
代码
- function (x) {
- return f(f)(x);
- }
参数函数的实际le运行结果函数,其实也就是说,无法保持f(f)返回函数的引用,每次引用都是不同的,所以才能够使得递归进行下去,不过引用相同,再没有函数算子名的情况下是不可能实现递归的