Javascript 闭包与高阶函数 ( 二 )
在上一篇 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 闭包与高阶函数 ( 二 )的更多相关文章
- Javascript 闭包与高阶函数 ( 一 )
		
上个月,淡丶无欲 让我写一期关于 闭包 的随笔,其实惭愧,我对闭包也是略知一二 ,不能给出一个很好的解释,担心自己讲不出个所以然来. 所以带着学习的目的来写一写,如有错误,忘不吝赐教 . 为什么要有闭 ...
 - JavaScript之闭包与高阶函数(一)
		
JavaScript虽是一门面向对象的编程语言,但同时也有许多函数式编程的特性,如Lambda表达式,闭包,高阶函数等. 函数式编程是种编程范式,它将电脑运算视为函数的计算.函数编程语言最重要的基础是 ...
 - JavaScript ES6函数式编程(一):闭包与高阶函数
		
函数式编程的历史 函数的第一原则是要小,第二原则则是要更小 -- ROBERT C. MARTIN 解释一下上面那句话,就是我们常说的一个函数只做一件事,比如:将字符串首字母和尾字母都改成大写,我们此 ...
 - [Node.js] 闭包和高阶函数
		
原文地址:http://www.moye.me/2014/12/29/closure_higher-order-function/ 引子 最近发现一个问题:一部分写JS的人,其实对于函数式编程的概念并 ...
 - JavaScript进阶之高阶函数篇
		
JavaScript进阶之高阶函数篇 简介:欢迎大家来到woo爷说前端:今天给你们带来的是JavaScript进阶的知识,接下来的系列都是围绕着JavaScript进阶进行阐述:首先我们第一篇讲的是高 ...
 - Python 进程线程协程 GIL 闭包 与高阶函数(五)
		
Python 进程线程协程 GIL 闭包 与高阶函数(五) 1 GIL线程全局锁  线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的 ...
 - 如何在JavaScript中使用高阶函数
		
将另一个函数作为参数的函数,或者定义一个函数作为返回值的函数,被称为高阶函数. JavaScript可以接受高阶函数.这种处理高阶函数的能力以及其他特点,使JavaScript成为非常适合函数式编程的 ...
 - javascript设计模式学习之三—闭包和高阶函数
		
一.闭包 闭包某种程度上就是函数的内部函数,可以引用外部函数的局部变量.当外部函数退出后,如果内部函数依旧能被访问到,那么内部函数所引用的外部函数的局部变量就也没有消失,该局部变量的生存周期就被延续. ...
 - 《JavaScript设计模式与开发实践》——第3章 闭包和高阶函数
		
闭包 变量的作用域和生存周期密切相关 高阶函数 函数可以作为参数被传递 函数可以作为返回值输出
 
随机推荐
- X-004 FriendlyARM tiny4412 uboot移植之点亮指路灯
			
<<<<<<<<<<<<<<<<<<<<<<<<< ...
 - centos 上网问题
			
前言:由于Linux下很多软件安装必须网络环境下进行,因此,对于如何在VMware下进行上网,我折腾了至少三天,今天上午,也即五一劳动节,终于搜到一遍技术文章,经过自己实践,VMware下Linux的 ...
 - Memcached源码分析之items.c
			
#include "memcached.h" #include <sys/stat.h> #include <sys/socket.h> #include ...
 - VB.NET中网络编程所需组件WinHTTP的添加
			
VB.NET中网络编程所需组件: WinHTTP组件:项目-->添加引用-->COM选项卡-->Microsoft WinHTTP Services,version 5.1--> ...
 - 详解Objective-C的meta-class                                                    分类:            ios相关             ios技术             2015-03-07 15:41    51人阅读    评论(0)    收藏
			
比较简单的一篇英文,重点是讲解meta-class.翻译下,加深理解. 原文标题:What is a meta-class in Objective-C? 原文地址:http://www.cocoaw ...
 - java.lang.ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig
			
问题描述: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with n ...
 - 安卓组件-BroadcastReceiver
			
[转]http://emilyzhou.blog.51cto.com/3632647/685387 一.BroadcastReceiver的简介 用于异步接收广播Intent,广播Intent的发送是 ...
 - 编写PHP规则
			
PHP是运行在服务器端的语言,可以动态生成html页面.这篇博客介绍它的一些编码规则. 一.基本规则 1.PHP代码总是用<?php和?>包围,例如 <?php echo " ...
 - 笔记-Python基础教程(第二版)第一章
			
第一章 快速改造:基础知识 01:整除.乘方 (Python3.0之前 如2.7版本) >>> 1/2 ==>0 1/2整除,普通除法: 解决办法1: 1.0/2.0 ==& ...
 - IM 之 融云
			
官方网站:http://www.rongcloud.cn 官方开发文档:http://www.rongcloud.cn/docs/ IM 融云 之 开发基础概念 IM 融云 之 通讯能力库API IM ...