必须将记忆函数定义为变量吗?

时间:2015-07-27 13:13:09

标签: javascript memoization

我刚问了这个问题(multiple errors while momoizing function inside another function),我得到了一个很好的答案......但是!为了更多地了解JavaScript,我想知道momoized函数是否可以用这种风格编写:

function main () {
    function memoized_f(){
        //memoizing code
    }
}

编辑:请注意我没有问上面代码有什么不同,我问是否有可能记住第二个代码!

那么,如何重写呢?

function main() {
  var create_node = (function() {
    var memo;
    console.log("memo: " + memo);
    console.log("create_node")

    function f() {
      var value;
      if (memo) {
        value = memo.cloneNode();
        console.log("clone node");
        console.log(value);
      } else {
        var value = document.createElement("div");
        value.innerHTML = "hello";
        console.log("new node");
        console.log("value: " + value);
        memo = value;
      }
      return value;
    }
    return f;
  })();
  var collection = [];
  for (var i = 0; i < 10; i++) {
    collection.push(create_node());
  };
  // Display results
  for (var i = 0; i < 10; i++) {
    console.log(i + ". " + collection[i]);
  }
}
main();

2 个答案:

答案 0 :(得分:1)

您的实际记忆功能是f(function(){ ... })() IIFE wrapping仅提供一个额外的闭包图层来隐藏变量memo,使其仅对f可见。

重复一遍:(function(){...})()表达式您的memoized函数。它是包装,它限制内部变量的可见性,并最终返回在其中定义的memoized函数f。如果您可以将memo公开给main中的其他代码并且不限制其仅对memoized函数的可见性,则可以完全取消IIFE包装并简单地将f重命名为{{1} }}:

create_node

如果您愿意,可以通过函数声明而不是IIFE来提供闭包:

function main() {
    var memo;

    function create_node() {
      var value;
      if (memo) { value = memo.cloneNode(); }
      else {
        var value = document.createElement("div");
        value.innerHTML = "hello";
        memo = value;
      }
      return value;
    }

  // use `create_node` as originally done
  // NOTE that other code can manipulate `memo` now, though!
}
main();

答案 1 :(得分:1)

由于javascript中的函数是一个对象,因此您可以使用该函数来记忆该值。我认为在fib example中更有意义,但这是你原来的帖子。

&#13;
&#13;
function main() {
  // memoizing function
  function create_node() {
    var value;
    // read from memo on function object
    if (create_node.memo) {
      value = create_node.memo.cloneNode();
      value.innerHTML = 'cloned';
      console.log("clone node");
      console.log(value);
    } else {
      var value = document.createElement("div");
      value.innerHTML = "hello";
      console.log("new node");
      console.log("value: " + value);
      // retain memo on the function object
      create_node.memo = value;
    }
    return value;
  }

  var collection = [];
  for (var i = 0; i < 10; i++) {
    collection.push(create_node());
  };
  // Display results
  for (var i = 0; i < 10; i++) {
    console.log(i + ". " + collection[i]);
    document.getElementById('container').appendChild(collection[i]);
  }
}

main();
&#13;
<div id="container"></div>
&#13;
&#13;
&#13;