JS偏函数、组合函数、缓存函数
JS偏函数、组合函数、缓存函数
一、JavaScript代码
[附件]/functools.js
- (function( window ) {
- "use strict";
- var functools = window.functools || {};
- /**
- * partial function
- */
- functools.curry = function( f, ctx ) {
- var args = Array.prototype.slice.call( arguments, 2 );
- return function() {
- var newArgs = args.concat(Array.prototype.slice.call( arguments ));
- return f.apply( ctx, newArgs );
- }
- }
- /**
- * right-left partial function
- */
- functools.rcurry = function( f, ctx ) {
- var args = Array.prototype.slice.call( arguments, 2 );
- return function() {
- var newArgs = Array.prototype.slice.call( arguments ).concat( args );
- return f.apply( ctx, newArgs );
- }
- }
- /**
- * composite function
- * @description `compose(f, g, x)(y) = f(g(y), x)`
- */
- functools.compose = function( f, g, f_ctx, g_ctx ) {
- var args_for_f = Array.prototype.slice.call( arguments, 4 );
- return function() {
- var args_for_g = Array.prototype.slice.call( arguments );
- var mid = g.apply( g_ctx, args_for_g );
- args_for_f.unshift(mid);
- return f.apply( f_ctx, args_for_f);
- }
- }
- /**
- * Memoizer, and allows multiple arguments.
- * @description Recursion needs to override function literal.
- * e.g. `func = memoize( func, null )`
- */
- functools.memoize = function( f, ctx ) {
- var memo = {};
- return function() {
- var key = Array.prototype.join.call(arguments, "_");
- var res = memo[ key ];
- if ( res === undefined ) {
- res = f.apply( ctx, arguments );
- memo[ key ] = res;
- }
- return res;
- }
- }
- /**
- * Return the result and runtime of the function.
- */
- functools.timeit = function( f, ctx ) {
- var args = Array.prototype.slice.call( arguments, 2 );
- var started = +new Date();
- var result = f.apply( ctx, args );
- var runtime = +new Date() - started;
- return {
- result: result,
- runtime: runtime
- }
- }
- function extend( a, b ) {
- for ( var prop in b ) {
- if ( b[ prop ] === undefined ) {
- delete a[ prop ];
- // Avoid "Member not found" error in IE8 caused by setting window.constructor
- } else if ( prop !== "constructor" || a !== window ) {
- a[ prop ] = b[ prop ];
- }
- }
- return a;
- }
- if ( window.functools === undefined ) {
- extend( window, functools );
- window.functools = functools;
- }
- // get at whatever the global object is, like window in browsers
- }( (function() {return this;}.call()) ));
二、QUnit测试代码
[附件]/functools.html
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>functools test case</title>
- <link rel="stylesheet" href="./qunit/qunit-1.11.0.css">
- </head>
- <body>
- <div id="qunit"></div>
- <div id="qunit-fixture"></div>
- <script src="./qunit/qunit-1.11.0.js"></script>
- <script src="./functools.js"></script>
- <script>
- test( "curry test case", function() {
- function sum() {
- var sum = 0;
- for ( var i = 0; i < arguments.length; i++ ) {
- sum += arguments[i];
- }
- return sum;
- }
- var sumBase10 = curry( sum, null, 1, 2, 3, 4 );
- var value = sumBase10( 20, 30, 40 );
- equal( value, 100, "We expect value to be 100" );
- });
- test( "rcurry test case", function() {
- function between( value, low, high, allowEqual ) {
- if ( value > low && value < high ) {
- return true;
- }
- if ( allowEqual && ( value == low || value == high) ) {
- return true;
- }
- return false;
- }
- var betweenClosed = rcurry( between, null, true ),
- between10and20 = rcurry( betweenClosed, null, 10, 20 );
- ok( between10and20( 10 ) , "10 is between 10 and 20" );
- ok( between10and20( 20 ) , "20 is between 10 and 20" );
- equal( between10and20( 9 ), false, "9 is not between 10 and 20" );
- equal( between10and20( 21 ), false, "21 is not between 10 and 20" );
- });
- test( "compose test case", function() {
- /* only one argument */
- function trim( s ) {
- return s.replace( /(^\s+)|(\s+$)/g, "" );
- }
- function upper( s ) {
- return s.toUpperCase();
- }
- var trimUpper = compose( upper, trim, null, null );
- var value = trimUpper( " trim and upper " );
- equal( value, "TRIM AND UPPER", "trimUpper test case" );
- /* multiple arguments */
- function f( x, y ) {
- return x + y;
- }
- var g = f;
- var fg = compose( f, g, null, null, "F" );
- equal( fg( "X", "Y" ), "XYF", "We expect value to be XYF" );
- });
- test( "memoize test case", function() {
- /* only one argument */
- function fib( n ) {
- if ( n == 0 ) return 0;
- if ( n == 1 ) return 1;
- return fib( n - 1) + fib( n - 2 );
- }
- var res_old = timeit( fib, null, 30 );
- fib = memoize( fib, null ); // override
- var res_new = timeit( fib, null, 30 );
- equal( res_new.result, res_old.result,
- [ "It's expected value.", res_old.runtime, res_new.runtime ].join("|")
- );
- /* multiple arguments */
- function func( a, b ) {
- func.counter++;
- if ( a == 1 ) return 1;
- return a + b + func( a - 1, b - 1 );
- }
- func = memoize( func, null ); // override
- func.counter = 0; // declare
- var a = func( 5, 4 ), // = 25
- a_cnt = func.counter; // = 5
- func.counter = 0; // reset
- var b = func( 6, 5 ), // 6 + 5 + func( 5, 4 ) << cache
- b_cnt = func.counter; // = 1
- equal( b, 36, [ "It's expected value.", a_cnt, b_cnt ].join("|") );
- });
- </script>
- </body>
- </html>
ps:附件解压,打开functools.html即可测试。
附件:http://down.51cto.com/data/2362319
本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/1138913,如需转载请自行联系原作者
JS偏函数、组合函数、缓存函数相关推荐
- 【JS函数】JS函数之高阶函数、组合函数、函数柯里化
自我介绍:大家好,我是吉帅振的网络日志:微信公众号:吉帅振的网络日志:前端开发工程师,工作4年,去过上海.北京,经历创业公司,进过大厂,现在郑州敲代码. JS函数专栏 1[JS函数]JS函数之普通.构 ...
- js map 箭头_JS异常函数之箭头函数
来源:logrocket作者:Maciej Cieślar 译者:前端小智 为了保证的可读性,本文采用意译而非直译. 在JS中,箭头函数可以像普通函数一样以多种方式使用.但是,它们一般用于需要匿名函数 ...
- js map 箭头_JS异常函数之-箭头函数
来源:logrocket 作者:Maciej Cieślar 译者:前端小智 为了保证的可读性,本文采用意译而非直译. 在JS中,箭头函数可以像普通函数一样以多种方式使用.但是,它们一般用于需要匿名函 ...
- 原生js已载入就执行函数_手写CommonJS 中的 require函数
前言 来自于圣松大佬的文章<手写CommonJS 中的 require函数> 什么是 CommonJS ? node.js 的应用采用的commonjs模块规范. 每一个文件就是一个模块, ...
- 【Scala】Scala的偏函数和偏应用函数
偏函数(Partial Function),是一个数学概念它不是"函数"的一种, 它跟函数是平行的概念. Scala中的Partia Function是一个Trait,其的类型为P ...
- JS进阶学习(作用域、函数进阶、解构赋值、原型链)
文章目录 1.面相对象编程介绍 2.ES6中的类和对象 3.类的继承 ES6中的类和对象 三个注意点 作用域 局部作用域 全局作用域 作用域链 JS垃圾回收机制(GC) JS垃圾回收机制-算法说明 闭 ...
- JS代码规范和基础函数的使用
JS中的一切都区分大小写(变量名,函数名,操作符) 标识符(变量名,函数名,属性名,函数的参数)按下列规则组合 就是如果要给某物起名字,按下述规则来 首字符必须是字母,下划线(_)或符号$ 其他字符可 ...
- Scala学习笔记(六) Scala的偏函数和偏应用函数
1. 偏函数 偏函数(Partial Function),是一个数学概念它不是"函数"的一种, 它跟函数是平行的概念. Scala中的Partia Function是一个Trait ...
- JS 高级(继承、函数)
JS 高级 继承 构造函数继承 <script>// 构造函数继承// 定义的Person类function Person(name, age) {this.name = name;thi ...
最新文章
- work1的code和问题
- html如何播放h264视频,浏览器 – 我如何播放H264视频?
- 微信小程序把玩(三)tabBar底部导航
- 【notebook】常用在线notebook总结
- leetcode - 300. 最长上升子序列
- ahp层次分析法软件_层次分析法在历史街区研究中的应用简析
- mysql5.7 json特性_【Mysql】Mysql5.7新特性之-json存储
- w25qxx SPI读取数据出来为全FF
- 2D游戏引擎开发入门(一)
- honeyd蜜罐简易部署——ubuntu
- 如何使iframe透明
- 小程序倒计时实现方法
- 2.4g和5g要不要合并_路由器2.4g和5g双频合一好还是分开好
- UVA - 10099 The Tourist Guide kruskal算法
- python均线斜率_一根20日均线闯天下? ——量化回测“压箱底指标”
- Powershell 数字转大写中文,数字金额转中文繁体(改自C#)
- Kalman滤波器从原理到实现
- buaa oo-unit3
- 记录一次使用Redis中ZSet和List分页
- 技术小黑屋的2015年