JS编程建议——66:使用函数实现历史记录

简介: 66:使用函数实现历史记录

建议66:使用函数实现历史记录
函数可以利用对象去记住先前操作的结果,从而能避免无谓的运算,这种优化称为记忆。JavaScript的对象和数组要实现这种优化是非常方便的。
例如,使用递归函数计算fibonacci数列。一个fibonacci数字是之前两个fibonacci数字之和。最前面的两个数字是0和1。
var fibonacci = function(n) {

return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);

};
for(var i = 0; i <= 10; i += 1) {

document.writeln('<br>' + i + ': ' + fibonacci(i));

}
返回下列值:
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
10: 55
在上面代码中,fibonacci函数被调用了453次,其中循环调用了11次,它自身调用了442次,去计算可能已刚计算过的值。如果使该函数具备记忆功能,就可以显著减少它的运算次数。
先使用一个临时数组保存存储结果,存储结果可以隐藏在闭包中。当函数被调用时,先看是否已经知道存储结果,如果已经知道,就立即返回这个存储结果。
var fibonacci = ( function() {

var memo = [0, 1];
var fib = function(n) {
    var result = memo[n];
    if( typeof result !== 'number') {
        result = fib(n - 1) + fib(n - 2);
        memo[n] = result;
    }
    return result;
};
return fib;

}());
for(var i = 0; i <= 10; i += 1) {

document.writeln('<br>' + i + ':' + fibonacci(i));

}
这个函数返回同样的结果,但它只被调用了29次,其中循环调用了11次,它自身调用了18次,去取得之前存储的结果。当然,可以把这种函数形式抽象化,以构造带记忆功能的函数。memoizer函数将取得一个初始的memo数组和fundamental函数。memoizer函数返回一个管理memo存储和在需要时调用fundamental函数的shell函数。memoizer函数传递这个shell函数和该函数的参数给fundamental函数。
var memoizer = function(memo, formula) {

var recur = function(n) {
    var result = memo[n];
    if( typeof result !== 'number') {
        result = formula(recur, n);
        memo[n] = result;
    }
    return result;
};
return recur;

};
现在,就可以使用memoizer来定义fundamental函数,提供初始的memo数组和fundamental函数。
var fibonacci = memoizer([0, 1], function(recur, n) {

return recur(n - 1) + recur(n - 2);

});
通过设计能产生其他函数的函数,可以极大地减少一些不必要的工作。例如,要产生一个可记忆的阶乘函数,只需提供基本的阶乘公式即可。
var factorial = memoizer([1, 1], function(recur, n) {

return n * recur(n - 1);

});

相关文章
|
2月前
|
存储 JavaScript 前端开发
JavaScript编程实现tab选项卡切换的效果+1
JavaScript编程实现tab选项卡切换的效果+1
|
3天前
|
JavaScript 前端开发 Java
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
本文介绍了JavaScript中常用的函数和方法,包括通用函数、Global对象函数以及数组相关函数。详细列出了每个函数的参数、返回值及使用说明,并提供了示例代码。文章强调了函数的学习应结合源码和实践,适合JavaScript初学者和进阶开发者参考。
13 2
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
|
2天前
|
前端开发 JavaScript 开发者
除了 Generator 函数,还有哪些 JavaScript 异步编程解决方案?
【10月更文挑战第30天】开发者可以根据具体的项目情况选择合适的方式来处理异步操作,以实现高效、可读和易于维护的代码。
|
8天前
|
自然语言处理 JavaScript 前端开发
JavaScript闭包:解锁编程潜能,释放你的创造力
【10月更文挑战第25天】本文深入探讨了JavaScript中的闭包,包括其基本概念、创建方法和实践应用。闭包允许函数访问其定义时的作用域链,常用于数据封装、函数柯里化和模块化编程。文章还提供了闭包的最佳实践,帮助读者更好地理解和使用这一强大特性。
11 2
|
16天前
|
JavaScript 前端开发
JavaScript 函数语法
JavaScript 函数是使用 `function` 关键词定义的代码块,可在调用时执行特定任务。函数可以无参或带参,参数用于传递值并在函数内部使用。函数调用可在事件触发时进行,如用户点击按钮。JavaScript 对大小写敏感,函数名和关键词必须严格匹配。示例中展示了如何通过不同参数调用函数以生成不同的输出。
|
18天前
|
存储 JavaScript 前端开发
JS函数提升 变量提升
【10月更文挑战第6天】函数提升和变量提升是 JavaScript 语言的重要特性,但它们也可能带来一些困惑和潜在的问题。通过深入理解和掌握它们的原理和表现,开发者可以更好地编写和维护 JavaScript 代码,避免因不了解这些机制而导致的错误和不一致。同时,不断提高对执行上下文等相关概念的认识,将有助于提升对 JavaScript 语言的整体理解和运用能力。
|
27天前
|
JavaScript 前端开发
js教程——函数
js教程——函数
24 4
|
26天前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
15 2
|
29天前
|
JavaScript 前端开发 Java
【javaScript数组,函数】的基础知识点
【javaScript数组,函数】的基础知识点
22 5
|
29天前
|
JavaScript 前端开发
Node.js 函数
10月更文挑战第5天
19 3