Reputation: 6054
I've just asked this question (multiple errors while momoizing function inside another function) and I've got a nice answer... but! Just to understand a little more about JavaScript, I'd like to know if the momoized function can be written in this style:
function main () {
function memoized_f(){
//memoizing code
}
}
EDIT: Please notice I'm not asking what is the difference in the code above, I'm asking if it is possible to memoize the second one!
So, how to rewrite this?
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();
Upvotes: 1
Views: 354
Reputation: 115950
Your actual memoized function is f
. The (function(){ ... })()
IIFE wrapping merely provides a an additional closure-layer to hide the variable memo
so that it is visible only to f
.
To repeat that: the (function(){...})()
expression is not your memoized function. It is wrapping that restricts visibility of an inner variable and ultimately returns your memoized function f
, which is defined inside of it. If you were okay with exposing memo
to other code in main
and not restrict its visibility to the memoized function only, you could eliminate the IIFE wrapping entirely and simply rename f
to create_node
:
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();
If you like, you can supply the closure wrapping via a function declaration instead of IIFE:
function createMemoizedFunc() {
var memo;
function f() {
var value;
if (memo) { value = memo.cloneNode(); }
else {
var value = document.createElement("div");
value.innerHTML = "hello";
memo = value;
}
return value;
}
return f;
}
var create_node = createMemoizedFunc();
Upvotes: 1
Reputation: 6948
Since functions in javascript are an object, you can just use that function to memoize the value. I think it would make more sense in fib example, but here is your original post.
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();
<div id="container"></div>
Upvotes: 1