在上一篇 中介绍了两个闭包的作用。 两位大佬留言指点,下来我会再研究闭包的实现原理和 Javascript 函数式编程 。
今天接到头条 HR 的邮件,真是超级开心呐,希望熬过一个周后一切顺利 ~
这一篇,继续举一些闭包的常见例子 。
我们常常需要面临下面的业务场景
- 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