Javascript 闭包与高阶函数 ( 二 )

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

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

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

提取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;
}

这样作可用,可是缺点不少 。
下面用一个闭包将其包装起来 。app

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

相关文章
相关标签/搜索