在上一篇 Javascript 闭包与高阶函数 ( 一 )中介绍了两个闭包的作用。 两位大佬留言指点,下来我会再研究闭包的实现原理和Javascript 函数式编程 。

今天接到头条 HR 的邮件,真是超级开心呐,希望熬过一个周后一切顺利 ~

这一篇,继续举一些闭包的常见例子 。

提取this

我们常常需要面临下面的业务场景

var push = Array.prototype.push;
var a = [];
push.call(a, 1);
console.log(a); // 1

这样固然可行,可是 我们有时候更想进行下面的操作

var a = [];
push(a, 1);
console.log(a); // 1

这应该怎么做呢? 思路就是将a 提取出来作为this,然后调用Array.prototype.push 方法 。

Function.prototype.uncharrying = function() {
var self = this; return function() {
var _this = Array.prototype.shift.call(arguments);
return self.apply(_this, arguments);
}
} var push = Array.prototype.push.uncharrying();
var a = [];
push(a, 1);
console.log(a);

函数节流

在很多业务场景中,比如 window.onresize 或者一些轮播图组件中,为了防止不断触发,都会使用一个函数节流的操作。下面看一个最简单的函数节流

var flag = false;

window.resize = function(e){
if(flag) {
return;
}
setTimeout(function(){
... // 业务逻辑代码 flag = false;
},1000);
flag = true;
}

这样做可用,但是缺点很多 。

下面用一个闭包将其包装起来 。

window.resize = (function(e){
var flag = false;
return function(){
if(flag) {
return;
}
setTimeout(function(){
... // 业务逻辑代码 flag = false;
},1000);
flag = true;
}
})();

看起来更加优优雅一点 。如果把节流的函数单独剥离呢??下面是完整代码

var throttle = function ( fn, interval ) { 

    var __self = fn,    // 保存需要被延迟执行的函数引用
timer, // 定时器
firstTime = true; // 是否是第一次调用 return function () {
var args = arguments,
__me = this; if ( firstTime ) { // 如果是第一次调用,不需延迟执行
__self.apply(__me, args);
return firstTime = false;
} if ( timer ) { // 如果定时器还在,说明前一次延迟执行还没有完成
return false;
} timer = setTimeout(function () { // 延迟一段时间执行
clearTimeout(timer);
timer = null;
__self.apply(__me, args); }, interval || 500 );
}; }; window.onresize = throttle(function(){
console.log( 1 );
}, 500 );

分时函数

与函数节流不同,分时函数用来限制函数调用的次数,用来提供页面性能 。

一个例子是创建 WebQQ的 QQ好友列表。列表中通常会有成百上千个好友,如果一个好友

用一个节点来表示,当我们在页面中渲染这个列表的时候,可能要一次性往页面中创建成百上千个节点。

在短时间内往页面中大量添加 DOM节点显然也会让浏览器吃不消,我们看到的结果往往就

是浏览器的卡顿甚至假死 。

这时候就需要分时函数,每隔一段时间运行一段 。

'use strict';

var timeChunk = function(argsAry, fn, count) {
var interval;
var exec = function() {
var l = argsAry.length;
for (var i = 0; i < Math.min(count || 1, l); i++) {
var arg = argsAry.shift();
fn(arg);
}
} return function() {
interval = setInterval(function() {
var flag = exec();
if (argsAry.length === 0) {
clearInterval(interval);
interval = null;
}
}, 500)
}
}; var a = [],func;
for (var i = 0; i < 36; i++) {
a.push(i);
} func = timeChunk(a, function(i) {
console.log(i);
}, 10)
func();

闭包和高阶函数的应用非常广泛,很多设计模式都是通过闭包和高阶函数来实现的 。

希望此文可以对你有帮助 。

转载请声明本文出处: http://www.cnblogs.com/likeFlyingFish/p/6426892.html

Javascript 闭包与高阶函数 ( 二 )的更多相关文章

  1. Javascript 闭包与高阶函数 ( 一 )

    上个月,淡丶无欲 让我写一期关于 闭包 的随笔,其实惭愧,我对闭包也是略知一二 ,不能给出一个很好的解释,担心自己讲不出个所以然来. 所以带着学习的目的来写一写,如有错误,忘不吝赐教 . 为什么要有闭 ...

  2. JavaScript之闭包与高阶函数(一)

    JavaScript虽是一门面向对象的编程语言,但同时也有许多函数式编程的特性,如Lambda表达式,闭包,高阶函数等. 函数式编程是种编程范式,它将电脑运算视为函数的计算.函数编程语言最重要的基础是 ...

  3. JavaScript ES6函数式编程(一):闭包与高阶函数

    函数式编程的历史 函数的第一原则是要小,第二原则则是要更小 -- ROBERT C. MARTIN 解释一下上面那句话,就是我们常说的一个函数只做一件事,比如:将字符串首字母和尾字母都改成大写,我们此 ...

  4. [Node.js] 闭包和高阶函数

    原文地址:http://www.moye.me/2014/12/29/closure_higher-order-function/ 引子 最近发现一个问题:一部分写JS的人,其实对于函数式编程的概念并 ...

  5. JavaScript进阶之高阶函数篇

    JavaScript进阶之高阶函数篇 简介:欢迎大家来到woo爷说前端:今天给你们带来的是JavaScript进阶的知识,接下来的系列都是围绕着JavaScript进阶进行阐述:首先我们第一篇讲的是高 ...

  6. Python 进程线程协程 GIL 闭包 与高阶函数(五)

    Python 进程线程协程 GIL 闭包 与高阶函数(五) 1 GIL线程全局锁 ​ 线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的 ...

  7. 如何在JavaScript中使用高阶函数

    将另一个函数作为参数的函数,或者定义一个函数作为返回值的函数,被称为高阶函数. JavaScript可以接受高阶函数.这种处理高阶函数的能力以及其他特点,使JavaScript成为非常适合函数式编程的 ...

  8. javascript设计模式学习之三—闭包和高阶函数

    一.闭包 闭包某种程度上就是函数的内部函数,可以引用外部函数的局部变量.当外部函数退出后,如果内部函数依旧能被访问到,那么内部函数所引用的外部函数的局部变量就也没有消失,该局部变量的生存周期就被延续. ...

  9. 《JavaScript设计模式与开发实践》——第3章 闭包和高阶函数

    闭包 变量的作用域和生存周期密切相关 高阶函数 函数可以作为参数被传递 函数可以作为返回值输出

随机推荐

  1. 【转】amCharts,一款值得推荐的Flash charts图组件

    今天无意中看到一个利用Flash生成chart图的工具:amCharts,我一开始就觉得这些chart图非常眼熟,它的显示样式跟监控宝的是完全一样的,我通过查看网页的源文件,才知道原来监控宝就是用的这 ...

  2. android studio 更新失败解决办法

    在andriod studio目录下找到studio.exe.vmoptions这个文件,用记事本打开,在后面加上 -Djava.net.preferIPv4Stack=true -Didea.upd ...

  3. AngularJS 讲解,四 Directive

    AngularJS  Directive 自定义指令(我最喜欢AngularJs的功能之一) 一:什么时候我们会用到directive 1.使html更具语义化,不用深入了解研究代码的逻辑便可知道大致 ...

  4. BootStrap TreeView使用示例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. listview 去掉header和footer中的分割线

    在listView中加上android:headerDividersEnabled="false" android:footerDividersEnabled="fals ...

  6. debugger 调试的一些经验

    1. 如果没有firebug , 可以用firebug-lite.js 内嵌的调试方式. 2. console.log 不是所有浏览器都支持console.log 在IE或者没有调试窗口的浏览器中,c ...

  7. windows批处理實例

    實例: 假設我們有個資料夾為d:\tmp和e:\tmp ,而我們只要將d:\tmp中有異動的檔案複製到e:\tmp下的話,用法如下 xcopy d:\tmp\. e:\tmp\ /D /S /Y 實例 ...

  8. box-sizing

    Over the generations, people realized that math is not fun, so a new CSS property called box-sizing ...

  9. ios自定义UIButton内部空间Rect

  10. 【BZOJ 3926】【ZJOI 2015】诸神眷顾的幻想乡

    http://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机的例题,感觉广义后缀自动机好恶心... 广义后缀自动机是对一个trie建立的后缀 ...