JS偏函数、组合函数、缓存函数

一、JavaScript代码

[附件]/functools.js

  1. (function( window ) {
  2. "use strict";
  3. var functools = window.functools || {};
  4. /**
  5. * partial function
  6. */
  7. functools.curry = function( f, ctx ) {
  8. var args = Array.prototype.slice.call( arguments, 2 );
  9. return function() {
  10. var newArgs = args.concat(Array.prototype.slice.call( arguments ));
  11. return f.apply( ctx, newArgs );
  12. }
  13. }
  14. /**
  15. * right-left partial function
  16. */
  17. functools.rcurry = function( f, ctx ) {
  18. var args = Array.prototype.slice.call( arguments, 2 );
  19. return function() {
  20. var newArgs = Array.prototype.slice.call( arguments ).concat( args );
  21. return f.apply( ctx, newArgs );
  22. }
  23. }
  24. /**
  25. * composite function
  26. * @description `compose(f, g, x)(y) = f(g(y), x)`
  27. */
  28. functools.compose = function( f, g, f_ctx, g_ctx ) {
  29. var args_for_f = Array.prototype.slice.call( arguments, 4 );
  30. return function() {
  31. var args_for_g = Array.prototype.slice.call( arguments );
  32. var mid = g.apply( g_ctx, args_for_g );
  33. args_for_f.unshift(mid);
  34. return f.apply( f_ctx, args_for_f);
  35. }
  36. }
  37. /**
  38. * Memoizer, and allows multiple arguments.
  39. * @description Recursion needs to override function literal.
  40. *              e.g. `func = memoize( func, null )`
  41. */
  42. functools.memoize = function( f, ctx ) {
  43. var memo = {};
  44. return function() {
  45. var key = Array.prototype.join.call(arguments, "_");
  46. var res = memo[ key ];
  47. if ( res === undefined ) {
  48. res = f.apply( ctx, arguments );
  49. memo[ key ] = res;
  50. }
  51. return res;
  52. }
  53. }
  54. /**
  55. * Return the result and runtime of the function.
  56. */
  57. functools.timeit = function( f, ctx ) {
  58. var args = Array.prototype.slice.call( arguments, 2 );
  59. var started = +new Date();
  60. var result = f.apply( ctx, args );
  61. var runtime = +new Date() - started;
  62. return {
  63. result: result,
  64. runtime: runtime
  65. }
  66. }
  67. function extend( a, b ) {
  68. for ( var prop in b ) {
  69. if ( b[ prop ] === undefined ) {
  70. delete a[ prop ];
  71. // Avoid "Member not found" error in IE8 caused by setting window.constructor
  72. } else if ( prop !== "constructor" || a !== window ) {
  73. a[ prop ] = b[ prop ];
  74. }
  75. }
  76. return a;
  77. }
  78. if ( window.functools === undefined ) {
  79. extend( window, functools );
  80. window.functools = functools;
  81. }
  82. // get at whatever the global object is, like window in browsers
  83. }( (function() {return this;}.call()) ));

二、QUnit测试代码

[附件]/functools.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>functools test case</title>
  6. <link rel="stylesheet" href="./qunit/qunit-1.11.0.css">
  7. </head>
  8. <body>
  9. <div id="qunit"></div>
  10. <div id="qunit-fixture"></div>
  11. <script src="./qunit/qunit-1.11.0.js"></script>
  12. <script src="./functools.js"></script>
  13. <script>
  14. test( "curry test case", function() {
  15. function sum() {
  16. var sum = 0;
  17. for ( var i = 0; i < arguments.length; i++ ) {
  18. sum +=  arguments[i];
  19. }
  20. return sum;
  21. }
  22. var sumBase10 = curry( sum, null, 1, 2, 3, 4 );
  23. var value = sumBase10( 20, 30, 40 );
  24. equal( value, 100, "We expect value to be 100" );
  25. });
  26. test( "rcurry test case", function() {
  27. function between( value, low, high, allowEqual ) {
  28. if ( value > low && value < high ) {
  29. return true;
  30. }
  31. if ( allowEqual && ( value == low || value == high) ) {
  32. return true;
  33. }
  34. return false;
  35. }
  36. var betweenClosed = rcurry( between, null, true ),
  37. between10and20 = rcurry( betweenClosed, null, 10, 20 );
  38. ok( between10and20( 10 ) , "10 is between 10 and 20" );
  39. ok( between10and20( 20 ) , "20 is between 10 and 20" );
  40. equal( between10and20( 9 ), false, "9 is not between 10 and 20" );
  41. equal( between10and20( 21 ), false, "21 is not between 10 and 20" );
  42. });
  43. test( "compose test case", function() {
  44. /* only one argument */
  45. function trim( s ) {
  46. return s.replace( /(^\s+)|(\s+$)/g, "" );
  47. }
  48. function upper( s ) {
  49. return s.toUpperCase();
  50. }
  51. var trimUpper = compose( upper, trim, null, null );
  52. var value = trimUpper( "  trim and upper  " );
  53. equal( value, "TRIM AND UPPER", "trimUpper test case" );
  54. /* multiple arguments */
  55. function f( x, y ) {
  56. return x + y;
  57. }
  58. var g = f;
  59. var fg = compose( f, g, null, null, "F" );
  60. equal( fg( "X", "Y" ), "XYF", "We expect value to be XYF" );
  61. });
  62. test( "memoize test case", function() {
  63. /* only one argument */
  64. function fib( n ) {
  65. if ( n == 0 ) return 0;
  66. if ( n == 1 ) return 1;
  67. return fib( n - 1) + fib( n - 2 );
  68. }
  69. var res_old = timeit( fib, null, 30 );
  70. fib = memoize( fib, null ); // override
  71. var res_new = timeit( fib, null, 30 );
  72. equal( res_new.result, res_old.result,
  73. [ "It's expected value.", res_old.runtime, res_new.runtime ].join("|")
  74. );
  75. /* multiple arguments */
  76. function func( a, b ) {
  77. func.counter++;
  78. if ( a == 1 ) return 1;
  79. return a + b + func( a - 1, b - 1 );
  80. }
  81. func = memoize( func, null ); // override
  82. func.counter = 0; // declare
  83. var a = func( 5, 4 ), // = 25
  84. a_cnt = func.counter; // = 5
  85. func.counter = 0; // reset
  86. var b = func( 6, 5 ), // 6 + 5 + func( 5, 4 ) << cache
  87. b_cnt = func.counter; // = 1
  88. equal( b, 36, [ "It's expected value.", a_cnt, b_cnt ].join("|") );
  89. });
  90. </script>
  91. </body>
  92. </html>

ps:附件解压,打开functools.html即可测试。

附件:http://down.51cto.com/data/2362319

本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/1138913,如需转载请自行联系原作者

JS偏函数、组合函数、缓存函数相关推荐

  1. 【JS函数】JS函数之高阶函数、组合函数、函数柯里化

    自我介绍:大家好,我是吉帅振的网络日志:微信公众号:吉帅振的网络日志:前端开发工程师,工作4年,去过上海.北京,经历创业公司,进过大厂,现在郑州敲代码. JS函数专栏 1[JS函数]JS函数之普通.构 ...

  2. js map 箭头_JS异常函数之箭头函数

    来源:logrocket作者:Maciej Cieślar 译者:前端小智 为了保证的可读性,本文采用意译而非直译. 在JS中,箭头函数可以像普通函数一样以多种方式使用.但是,它们一般用于需要匿名函数 ...

  3. js map 箭头_JS异常函数之-箭头函数

    来源:logrocket 作者:Maciej Cieślar 译者:前端小智 为了保证的可读性,本文采用意译而非直译. 在JS中,箭头函数可以像普通函数一样以多种方式使用.但是,它们一般用于需要匿名函 ...

  4. 原生js已载入就执行函数_手写CommonJS 中的 require函数

    前言 来自于圣松大佬的文章<手写CommonJS 中的 require函数> 什么是 CommonJS ? node.js 的应用采用的commonjs模块规范. 每一个文件就是一个模块, ...

  5. 【Scala】Scala的偏函数和偏应用函数

    偏函数(Partial Function),是一个数学概念它不是"函数"的一种, 它跟函数是平行的概念. Scala中的Partia Function是一个Trait,其的类型为P ...

  6. JS进阶学习(作用域、函数进阶、解构赋值、原型链)

    文章目录 1.面相对象编程介绍 2.ES6中的类和对象 3.类的继承 ES6中的类和对象 三个注意点 作用域 局部作用域 全局作用域 作用域链 JS垃圾回收机制(GC) JS垃圾回收机制-算法说明 闭 ...

  7. JS代码规范和基础函数的使用

    JS中的一切都区分大小写(变量名,函数名,操作符) 标识符(变量名,函数名,属性名,函数的参数)按下列规则组合 就是如果要给某物起名字,按下述规则来 首字符必须是字母,下划线(_)或符号$ 其他字符可 ...

  8. Scala学习笔记(六) Scala的偏函数和偏应用函数

    1. 偏函数 偏函数(Partial Function),是一个数学概念它不是"函数"的一种, 它跟函数是平行的概念. Scala中的Partia Function是一个Trait ...

  9. JS 高级(继承、函数)

    JS 高级 继承 构造函数继承 <script>// 构造函数继承// 定义的Person类function Person(name, age) {this.name = name;thi ...

最新文章

  1. work1的code和问题
  2. html如何播放h264视频,浏览器 – 我如何播放H264视频?
  3. 微信小程序把玩(三)tabBar底部导航
  4. 【notebook】常用在线notebook总结
  5. leetcode - 300. 最长上升子序列
  6. ahp层次分析法软件_层次分析法在历史街区研究中的应用简析
  7. mysql5.7 json特性_【Mysql】Mysql5.7新特性之-json存储
  8. w25qxx SPI读取数据出来为全FF
  9. 2D游戏引擎开发入门(一)
  10. honeyd蜜罐简易部署——ubuntu
  11. 如何使iframe透明
  12. 小程序倒计时实现方法
  13. 2.4g和5g要不要合并_路由器2.4g和5g双频合一好还是分开好
  14. UVA - 10099 The Tourist Guide kruskal算法
  15. python均线斜率_一根20日均线闯天下? ——量化回测“压箱底指标”
  16. Powershell 数字转大写中文,数字金额转中文繁体(改自C#)
  17. Kalman滤波器从原理到实现
  18. buaa oo-unit3
  19. 记录一次使用Redis中ZSet和List分页
  20. 技术小黑屋的2015年

热门文章

  1. android studio怎么改软件扫码界面_一文入门Android逆向
  2. 强化学习-入门教程(完整版)
  3. Android原生(Native)C开发
  4. TF实战丨使用Vagrant安装Tungsten Fabric
  5. MIDI二进制文件格式简析
  6. 管理者需换位思考 员工都是CEO
  7. @TableField fill
  8. JavaSE实现桌面屏幕下雪功能
  9. ArcGIS Server 自定义比例尺切图
  10. daphile的dsd设置_小块头有大能量 篇二:JaguarBoard之Daphile HiFi 畅享