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 相关文章推荐
IE浏览器兼容Firefox的JS脚本的代码
Oct 23 Javascript
jQuery EasyUI API 中文文档 - ComboTree组合树
Oct 11 Javascript
JQuery设置和去除disabled属性的5种方法总结
May 16 Javascript
jquery索引在使用中的一些困惑
Oct 24 Javascript
封装了jQuery的Ajax请求全局配置
Feb 05 Javascript
深入浅析Extjs中store分组功能的使用方法
Apr 20 Javascript
第七章之菜单按钮图标组件
Apr 25 Javascript
jquery中live()方法和bind()方法区别分析
Jun 23 Javascript
bootstrap datetimepicker2.3.11时间插件使用
Nov 19 Javascript
jQuery Mobile漏洞会有跨站脚本攻击风险
Feb 12 Javascript
基于Vue 服务端Cookies删除的问题
Sep 21 Javascript
JQuery事件委托原理与用法实例分析
May 13 jQuery
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
php中用socket模拟http中post或者get提交数据的示例代码
2013/08/08 PHP
php截取字符串函数substr,iconv_substr,mb_substr示例以及优劣分析
2014/06/10 PHP
prototype 中文参数乱码解决方案
2009/11/09 Javascript
jQuery选择头像并实时显示的代码
2010/06/27 Javascript
JavaScript实现随机替换图片的方法
2015/04/16 Javascript
搞定immutable.js详细说明
2016/05/02 Javascript
JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax
2016/05/15 Javascript
浅谈JavaScript 执行环境、作用域及垃圾回收
2016/05/31 Javascript
Node层模拟实现multipart表单的文件上传示例
2018/01/02 Javascript
vue-cli webpack 引入jquery的方法
2018/01/10 jQuery
用jQuery将JavaScript对象转换为querystring查询字符串的方法
2018/11/12 jQuery
vue filter 完美时间日期格式的代码
2019/08/14 Javascript
vue实现树形结构样式和功能的实例代码
2019/10/15 Javascript
ElementUI多个子组件表单的校验管理实现
2019/11/07 Javascript
js删除指定位置超链接中含有百度与360的标题
2021/01/06 Javascript
Python3中常用的处理时间和实现定时任务的方法的介绍
2015/04/07 Python
PyQt5实现拖放功能
2018/04/25 Python
Python可以实现栈的结构吗
2020/05/27 Python
python中count函数知识点浅析
2020/12/17 Python
canvas使用注意点总结
2013/07/19 HTML / CSS
详解canvas绘制多张图的排列顺序问题
2019/01/21 HTML / CSS
新西兰最大的品牌运动鞋购物网站:Platypus NZ
2017/10/27 全球购物
美国保健品专家:Life Extension
2018/05/04 全球购物
本科生的职业生涯规划范文
2014/01/09 职场文书
高考备战决心书
2014/03/11 职场文书
法人授权委托书范本
2014/04/04 职场文书
爱与责任演讲稿
2014/05/20 职场文书
公务员学习习总书记“三严三实”思想汇报
2014/09/19 职场文书
司法局2014法制宣传日活动总结
2014/11/01 职场文书
抄袭同学作业检讨书1000字
2014/11/20 职场文书
2014年劳动部工作总结
2014/12/11 职场文书
2015年银行客户经理工作总结
2015/04/01 职场文书
办公室行政主管岗位职责
2015/04/09 职场文书
王亚平太空授课观后感
2015/06/12 职场文书
班主任工作总结范文
2015/08/13 职场文书
2015年党务工作者个人工作总结
2015/10/22 职场文书