underscore之function_动力节点Java学院整理


Posted in Javascript onJuly 11, 2017

因为underscore本来就是为了充分发挥JavaScript的函数式编程特性,所以也提供了大量JavaScript本身没有的高阶函数。

bind

bind()有什么用?我们先看一个常见的错误用法:

'use strict';
console.log('Hello, world!');
// 输出'Hello, world!'
var log = console.log;
log('Hello, world!');
// Uncaught TypeError: Illegal invocation

如果你想用log()取代console.log(),按照上面的做法是不行的,因为直接调用log()传入的this指针是undefined,必须这么用:

'use strict';
var log = console.log;
// 调用call并传入console对象作为this:
log.call(console, 'Hello, world!')
// 输出Hello, world!

这样搞多麻烦!还不如直接用console.log()。但是,bind()可以帮我们把console对象直接绑定在log()的this指针上,以后调用log()就可以直接正常调用了:

'use strict';
var log = _.bind(console.log, console);
log('Hello, world!');
// 输出Hello, world!

partial

partial()就是为一个函数创建偏函数。偏函数是什么东东?看例子:

假设我们要计算xy,这时只需要调用Math.pow(x, y)就可以了。

假设我们经常计算2y,每次都写Math.pow(2, y)就比较麻烦,如果创建一个新的函数能直接这样写pow2N(y)就好了,这个新函数pow2N(y)就是根据Math.pow(x, y)创建出来的偏函数,它固定住了原函数的第一个参数(始终为2):

'use strict';
var pow2N = _.partial(Math.pow, 2);
pow2N(3); // 8
pow2N(5); // 32
pow2N(10); // 1024

如果我们不想固定第一个参数,想固定第二个参数怎么办?比如,希望创建一个偏函数cube(x),计算x3,可以用_作占位符,固定住第二个参数:

'use strict';
var cube = _.partial(Math.pow, _, 3);
cube(3); // 27
cube(5); // 125
cube(10); // 1000

可见,创建偏函数的目的是将原函数的某些参数固定住,可以降低新函数调用的难度。

memoize

如果一个函数调用开销很大,我们就可能希望能把结果缓存下来,以便后续调用时直接获得结果。举个例子,计算阶乘就比较耗时:

'use strict';
function factorial(n) {
  console.log('start calculate ' + n + '!...');
  var s = 1, i = n;
  while (i > 1) {
    s = s * i;
    i --;
  }
  console.log(n + '! = ' + s);
  return s;
}
factorial(10); // 3628800
// 注意控制台输出:
// start calculate 10!...
// 10! = 3628800
用memoize()就可以自动缓存函数计算的结果:
'use strict';
var factorial = _.memoize(function(n) {
  console.log('start calculate ' + n + '!...');
  var s = 1, i = n;
  while (i > 1) {
    s = s * i;
    i --;
  }
  console.log(n + '! = ' + s);
  return s;
});
// 第一次调用:
factorial(10); // 3628800
// 注意控制台输出:
// start calculate 10!...
// 10! = 3628800
// 第二次调用:
factorial(10); // 3628800
// 控制台没有输出

对于相同的调用,比如连续两次调用factorial(10),第二次调用并没有计算,而是直接返回上次计算后缓存的结果。不过,当你计算factorial(9)的时候,仍然会重新计算。

可以对factorial()进行改进,让其递归调用:

'use strict';
var factorial = _.memoize(function(n) {
  console.log('start calculate ' + n + '!...');
  if (n < 2) {
    return 1;
  }
  return n * factorial(n - 1);
});
factorial(10); // 3628800
// 输出结果说明factorial(1)~factorial(10)都已经缓存了:
// start calculate 10!...
// start calculate 9!...
// start calculate 8!...
// start calculate 7!...
// start calculate 6!...
// start calculate 5!...
// start calculate 4!...
// start calculate 3!...
// start calculate 2!...
// start calculate 1!...
factorial(9); // 362880
// console无输出

once

顾名思义,once()保证某个函数执行且仅执行一次。如果你有一个方法叫register(),用户在页面上点两个按钮的任何一个都可以执行的话,就可以用once()保证函数仅调用一次,无论用户点击多少次:

'use strict';
var register = _.once(function () {
  alert('Register ok!');
});
// 测试效果:
register();
register();
register();

 delay

delay()可以让一个函数延迟执行,效果和setTimeout()是一样的,但是代码明显简单了:

'use strict';
// 2秒后调用alert():
_.delay(alert, 2000);
如果要延迟调用的函数有参数,把参数也传进去:
'use strict';
var log = _.bind(console.log, console);
_.delay(log, 2000, 'Hello,', 'world!');
// 2秒后打印'Hello, world!':
Javascript 相关文章推荐
来自chinaz的ajax获取评论代码
May 03 Javascript
js 数组克隆方法 小结
Mar 20 Javascript
JS面向对象编程 for Cookie
Sep 19 Javascript
Node.js的特点和应用场景介绍
Nov 04 Javascript
javascript数组输出的两种方式
Jan 13 Javascript
JS区分浏览器页面是刷新还是关闭
Apr 17 Javascript
AngularJS 指令详细介绍
Jul 27 Javascript
javascript宿主对象之window.navigator详解
Sep 07 Javascript
jquery实现input框获取焦点的简单实例
Jan 26 Javascript
JavaScript实现精美个性导航栏筋斗云效果
Oct 29 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
Mar 08 Javascript
微信小程序使用canvas的画图操作示例
Jan 18 Javascript
ReactNative实现图片上传功能的示例代码
Jul 11 #Javascript
手把手教你搭建ES6的开发运行环境
Jul 11 #Javascript
ReactNative之键盘Keyboard的弹出与消失示例
Jul 11 #Javascript
react-native 封装选择弹出框示例(试用ios&amp;android)
Jul 11 #Javascript
vue.js内部自定义指令与全局自定义指令的实现详解(利用directive)
Jul 11 #Javascript
javascript 玩转Date对象(实例讲解)
Jul 11 #Javascript
使用jQuery实现动态添加小广告
Jul 11 #jQuery
You might like
追求程序速度,而不是编程的速度
2008/04/23 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
phpstudy隐藏index.php的方法
2020/09/21 PHP
JavaScript异步编程:异步数据收集的具体方法
2013/08/19 Javascript
js动态设置div的值下例子
2013/10/29 Javascript
showModalDialog在谷歌浏览器下会返回Null的解决方法
2013/11/27 Javascript
java和javascript获取word文档的书签位置对比
2014/06/19 Javascript
JavaScript中常用的六种互动方法示例
2015/03/13 Javascript
jQuery时间插件jquery.clock.js用法实例(5个示例)
2016/01/14 Javascript
AngularJS 指令详细介绍
2016/07/27 Javascript
Vue2 使用 Echarts 创建图表实例代码
2017/05/18 Javascript
jquery实现图片轮播器
2017/05/23 jQuery
ES6中箭头函数的定义与调用方式详解
2017/06/02 Javascript
微信小程序自定义select下拉选项框组件的实现代码
2018/08/28 Javascript
javascript原型链学习记录之继承实现方式分析
2019/05/01 Javascript
[28:42]Ti4正赛VG vs NEWBEE1
2014/07/19 DOTA
[03:30]完美盛典趣味短片 CSGO2019年度名场面
2019/12/07 DOTA
Python小程序 控制鼠标循环点击代码实例
2019/10/08 Python
python 实现return返回多个值
2019/11/19 Python
python实现吃苹果小游戏
2020/03/21 Python
python小程序基于Jupyter实现天气查询的方法
2020/03/27 Python
Django中日期时间型字段进行年月日时分秒分组统计
2020/11/27 Python
css3 响应式媒体查询的示例代码
2019/09/25 HTML / CSS
HTML5中通过li-canvas轻松实现单图、多图、圆角图绘制,单行文字、多行文字等
2018/11/30 HTML / CSS
挪威户外活动服装和装备购物网站:Bergfreunde挪威
2016/10/20 全球购物
SmartBuyGlasses英国:购买太阳镜和眼镜
2018/01/29 全球购物
意大利婴儿产品网上商店:Mukako
2018/10/14 全球购物
社区助残日活动总结
2014/08/29 职场文书
小学生九一八纪念日83周年演讲稿500字
2014/09/17 职场文书
开平碉楼导游词
2015/02/06 职场文书
员工辞职信怎么写
2015/02/27 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书
市场营销计划书
2019/04/24 职场文书
2019下半年英语教师的教学工作计划(3篇)
2019/09/25 职场文书
html+css合并表格边框的示例代码
2021/03/31 HTML / CSS
数据库之SQL技巧整理案例
2021/07/07 SQL Server