记忆函数必须定义为变量吗?
Must memoized functions be defined as variables?
我刚刚问了这个问题 (),我得到了一个很好的答案...但是!只是为了更多地了解 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();
您实际记忆的函数是f
。 (function(){ ... })()
IIFE wrapping 仅仅提供了一个额外的闭包层来隐藏变量 memo
以便它只对 f
.
可见
重复一遍:(function(){...})()
表达式 不是 你的记忆函数。包装限制了内部变量的可见性,最终 returns 你的记忆函数 f
,它是在它内部定义的。如果您可以将 memo
暴露给 main
中的其他代码并且不限制其仅对记忆函数的可见性,您可以完全消除 IIFE 包装并简单地将 f
重命名为 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();
如果愿意,您可以通过函数声明而不是 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();
由于 javascript 中的函数是一个对象,您可以只使用该函数来记忆值。我认为在 fib example 中更有意义,但这是您的原始 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>
我刚刚问了这个问题 (
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();
您实际记忆的函数是f
。 (function(){ ... })()
IIFE wrapping 仅仅提供了一个额外的闭包层来隐藏变量 memo
以便它只对 f
.
重复一遍:(function(){...})()
表达式 不是 你的记忆函数。包装限制了内部变量的可见性,最终 returns 你的记忆函数 f
,它是在它内部定义的。如果您可以将 memo
暴露给 main
中的其他代码并且不限制其仅对记忆函数的可见性,您可以完全消除 IIFE 包装并简单地将 f
重命名为 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();
如果愿意,您可以通过函数声明而不是 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();
由于 javascript 中的函数是一个对象,您可以只使用该函数来记忆值。我认为在 fib example 中更有意义,但这是您的原始 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>