multiple errors while momoizing function inside an

2019-08-02 16:48发布

问题:

I have something like this:

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

        function f() {
          var value;
          console.log(value);

          if (memo) {
            value = memo.cloneNode();
            console.log("clone node");
            console.log(value);
          } else {
            var value = document.createElement("div");
            var style = "";
            value.setAttribute("style", style);
            value.innerHTML = "hello";
            console.log("new node");
            console.log(value);
          }
          return value;
        }
        return f;
      })();
  }
  var colection = [];
  for (var i = 0; i < 10; i++) {
    colection.push(create_node());
  };
}
main();

the problem is I get an error (in firefox at least) while try to log "create_node". Also, if I don't return f(), instead of f, it doesn't get executed. In any case, memo is always undefined. So I have this three problems here. I guess they come from a lack of understanding on complex closures, so I'd need a Javascript rockstar to enlighten me!

回答1:

As I can't comment, I have to post a reply.

I have seen multiple issues in your code:

  • The create_node function doesn't have a return. So, your collection will always be empty.
  • You are defining two vars in the f function with the name "value". the second var value might be a bug.
  • The var memo is never assigned.
  • while you are returning f inside your anonymous function, you are not executing it.

I am guessing you are trying to do something like that:

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

        if (memo) {
          value = memo.cloneNode();
          console.log("clone node" + value);
        } else {
          value = document.createElement("div");
          var style = "";
          value.setAttribute("style", style);
          value.innerHTML = "hello";
          console.log("new node:" + value.innerHTML);
        }
        return value;
      }
      return f;

    })()();
   return memo
  }
  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]); }
}


回答2:

I found the answer to my own question:

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");
            memo = value;
        }
        console.log("new node");
        console.log("value: "+value);
        return value;
    }
    return f;
})();