3

我最近开始学习 JS,这是我第一次涉足函数式语言领域。

在 npm 模块中做“蹦床”练习,functional-javascript-workshop发现我自己的解决方案和官方解决方案之间有一个有趣的区别。两者都工作得很好,但我不知道它们之间的实际区别到底是什么。我非常了解自己的解决方案,但不完全理解为什么另一个也有效。

我的解决方案

function repeat(op, num) {
  var _repeat = function() {
    if (num <= 0) return;
    op();
    return repeat(op, --num);
  };

  return _repeat;
}

function trampoline(f) {
  while (f instanceof Function) {
    f = f();
  }
  return f;
}

module.exports = function(op, num) {
  return trampoline(repeat(op, num));
};

官方解决方案

function repeat(operation, num) {
  return function() {
    if (num <= 0) return
    operation()
    return repeat(operation, --num)
  }
}

function trampoline(fn) {
  while(fn && typeof fn === 'function') {
    fn = fn()
  }
}

module.exports = function(operation, num) {
  trampoline(function() {
    return repeat(operation, num)
  })
}

具体来说,我对最后一部分很好奇——为什么官方解决方案会创建一个匿名函数而不是仅仅传递repeat

4

2 回答 2

1

看看蹦床:

   function trampoline(fn) {
      while(fn && typeof fn === 'function') {
        fn = fn()
      }
    }

请注意,只要fn是它调用的函数,它就会一直迭代。

所以理论上你可以有尽可能多的嵌套函数并得到相同的结果:

module.exports = function(operation, num) {
  trampoline(function() {
    return function() {
        return function() {
           return repeat(operation, num);
        };
    };
  });
};

演示:http: //jsbin.com/yixaliyoye/1/edit

官方解决方案比您的解决方案多了一个冗余步骤。没有真正的原因,除了原作者可能认为它看起来更具可读性。

于 2014-11-17T23:19:46.577 回答
1

真的没有什么理由。

除了蹦床可能会进行所有调用,而在您的版本中,第一次调用repeat是在它之外完成的。这可能被认为更干净,并且在trampoline更复杂时可能会产生实际差异(例如,将所有执行包装在 try-catch 中)。

于 2014-11-17T23:53:42.120 回答