透过Extjs学习JavaScript---闭包篇
2014-02-19 11:15
148 查看
目录
一、前言二、基础讲解
三、知识应用
四、总结
五、常见问题
一、前言
JavaScript设计得最出色的就是它的函数的实现,它几乎接近于完美。我们现在现就来介绍它其中一个功能“闭包”。我们可以利用闭包“保存变量生命周期”和“屏蔽变量”的特性优雅地完成一些强大的功能。后面我还会介绍在ExtJS中是如何使用这种特性的。二、基础讲解
我们可以利用“闭包”功能来实现隐藏或公开对象的变量和方法。测试代码如下
var bufferObj = (function createFun(fn, interval, scope) { var isExec = 1;//被闭包的变量,外界不能直接访问 return {//公开set,和exec方法 set : function(data) { isExec = data; }, exec : function(fn) { if (isExec) {//读取闭包的变量 console.log("函数可以执行"); fn(); } else { console.log("函数不能执行"); } } }; })();
注意我们把整个函数用括号包住,并在最后一行加了"()",这样写法的意思是马上执行函数,并返回了结果值。这样我们的变量“bufferObj”对象就是带有公开的set和exec方法和私有变量“isExec”。我不能直接访问到“isExec”这个变量,这就是我们使用闭包的结果,将一些变量或方法优雅的变成私有,很好的控制了变量的作用域。
三、知识应用
上节初步的说明了闭包的写法和功能,看似功能不过如此,其实不然。下面我们来看看ExtJs是如何使用闭包功能的,希望可以给大家在使用闭包有更多的启发。这也是学习JS这门语言有兴趣的地方,是把一个简简单单的知识点写出多种花样。下面的代码是extjs中“Ext.Function”类中的“createBuffered”方法,主要功能就是生成“带有延迟功能的函数”。我为了简化“Ext.Function”类的上下文,并把代码标上的汉语解释方便讲解。
Ext.Function 代码如下:
var Ext = {}; Ext.Function = { /** * 返回带有延迟功能的函数,如果在延迟的时间内再次调用该函数,重置缓冲时间 * @param {Function} fn 需要被延迟的方法 * @param {Number} buffer 延迟时间(毫秒) * @param {Object} [scope=this] 传入方法的作用域 * @param {Array} [args] 方法参数 * @return {Function} 返回带有缓冲功能的函数 */ createBuffered: function(fn, buffer, scope, args) { var timerId;//计时器ID return function() { var callArgs = args || Array.prototype.slice.call(arguments, 0),//将“arguments”类型转成数组类型 me = scope || this;//如果没有传入“scope”参数就全用当前上下文的"this"为作用域 if (timerId) {//如果有计时器,就取消之前的计时器 clearTimeout(timerId); } timerId = setTimeout(function(){//重置缓冲时间 fn.apply(me, callArgs);//在相应的作用域上执行方法 }, buffer); }; } };
在上述代码中把变量“timerId”闭包在对象内,只返回了一个带有缓冲功能的方法,该返回方法主要是判断函数在缓冲期内是否被重复调用,如果在缓冲期内被调用就重置计时器。
在代码中有三个知识点:
1. 15行中“Array.prototype.slice.call(arguments, 0)”这句意思是把arguments参数类型转成数组类型,方便第23行的“apply”调用。(如果不知道arguments是什么意思的同学就自行面壁思过吧,哈哈哈。)
2. 16行中"me = scope || this" ,是一个if判断取巧的写法。整句的意思是,当“scope”为“空”或“假”时就把“this”返回给“me”变量。
3. 18行中的“timerId”变量由于是被闭包,他的“生命期”被延长了,不会随着返回函数的运行结束而结束,所以每次调用返回函数时,都可以保留之前的“timerId”值。
使用代码如下:
var run = function(data) { alert("函数运行成功"); alert("入参为:" + data); }; var bufferFn = Ext.Function.createBuffered(run, 3000); bufferFn("JavaScript1");//不会被执行,因为后一个函数在缓冲期3秒内调用,把这当前的函数取消了 bufferFn("JavaScript2");//不会被执行,因为后一个函数在缓冲期3秒内调用,把这当前的函数取消了 bufferFn("JavaScript3");//会被执行,因为后一个函数没有在缓冲期3秒内调用,所以该函数会执行 setTimeout(function() {//间隔4秒 bufferFn("JavaScript4");//会被执行,因为后面没有重复调用了 }, 4000);
在上述代码第5行,就是通过“Ext.Function.createBuffered”生成了一个带有缓冲功能的函数“bufferFn”,如果我们在3秒的缓冲期内重复调用就不会重复执行函数。
四、总结
笔者的案例代码是取自于ExtJs,可能有些不好理解,但是当你看懂了,就能感觉到JS这门语言的巧妙。文本只是通过介绍闭包的方法,进而介绍下ExtJs的源码,使我们撸代码的水平有所提升。
五、常见问题
问:有的人会问这创建延迟函数有什么用?感觉在实际情况下用不到?答:笔者可不这么认为,我在做项目中就常常用到这种方法。当我们要对一个输入框发生内容改变时,进行AJAX查询。但又不想每输入一个字就进行一次查询,因为这样非常的消耗服务器资源。较好的解决方案是设置一个输入缓冲期,在这个输入缓冲期内输入字母不进行查询,等过了缓冲期在对之前输入过的所有字母进行查询,所以我们需要一个“带有延迟缓冲功能”的函数。
问:arguments这到底是什么?
答:好吧,详细请访问http://www.w3school.com.cn/js/pro_js_functions_arguments_object.asp,arguments是一个特殊的对象,类似于数组,但不完全是数组,所以要用“Array.prototype.slice.call(arguments, 0)”方法转成常规的数组。
相关文章推荐
- ext4 学习笔记(七)[ExtJS扩展原生Javascript](白鹤翔第一季)
- myEclipse7.5中安装 javascript,extjs的代码自动提示spket插件和extjs desiner可视化代码生成工具,extjs的一个很好的学习视频资源地址
- 开始学习JAVASCRIPT 学校要我参加一个项目 要用EXTJS 晕!!
- ExtJS学习-----------Ext.String,ExtJS对javascript中的String的扩展
- ExtJS学习-----------Ext.Number,ExtJS对javascript中的Number的扩展
- ExtJS学习------Ext.define的继承extend,用javascript实现相似Ext的继承
- ExtJS学习-----------Ext.Array,ExtJS对javascript中的Array的扩展(实例)
- ExtJS学习-----------Ext.Array,ExtJS对javascript中的Array的扩展
- 轻松学习JavaScript二十一:DOM编程学习之获取元素节点的子节点和属性节点
- 【JavaScript学习】基本包装类型
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<javascript>(三十)
- javascript 学习笔记
- 八张思维导图学习JavaScript
- 跟我学习javascript的执行上下文
- JavaScript学习-DOM扩展_元素遍历
- EXTJS学习二
- javascript 学习总结(九)面向对象编程
- JavaScript高级程序设计(第三版)学习笔记8、9、10章
- 韩顺平_轻松搞定网页设计(html+css+javascript)_第30讲_类和对象细节_创建对象的几种方式_js对象内存分析_学习笔记_源代码图解_PPT文档整理
- javascript学习笔记之document.compatMode