初识js中的闭包
今天看了关于js闭包方面的文章,还是有些云里雾里,对于一个菜鸟来说,学习闭包确实有一定的难度,不说别的,能够在网上找到一篇优秀的是那样的不易。
当然之所以闭包难理解,个人觉得是基础知识掌握的不牢,因为闭包牵扯到一些前面的东西,比如作用域\等等,如果连基本的作用域都没有弄清楚,自然不可能搞懂闭包,还有就是对js的实践比较少,因为你根本就不知道什么时候要用这东西,自然谈不上对闭包的深刻理解。
今天我就简单的说说我目前所理解的闭包,当然可能不完全正确,但是我相信会给你一定的启发。
首先我们来谈谈js中的变量,如果你不知道我为什么要说这些,那么你根本没有掌握js的基础,建议回头复习。
js中分:全局变量 和 局部变量
全局变量:可以在任意位置访问的量就叫全局变量
1 var age = 20;
2 function a(){
3 console.log(age); >>20
4 }
5 a();
局部变量:函数中用var定义的变量,只能在函数中访问这个变量,函数外部访问不了。
1 function a(){
2 var age = 20;
3 }
4 a();
5 console.log(age); >> Uncaught ReferenceError: age is not defined
注意点1:在函数中如果不使用var定义变量那么js引擎会自动添加成全局变量。
注意点2:全局变量从创建的那一刻起就会一直保存在内存中,除非你关闭这个页面,局部变量当函数运行完以后就会销毁这个变量,假如有多次调用这个函数它下一次调用的时候又会重新创建那个变量,既运行完就销毁,回到最初的状态,简单来说局部变量是一次性的,用完就扔,下次要我再重新创建。
函数的相关知识点:
1. 一个函数内可以嵌套多个函数
2. 函数里面的子函数可以访问它上级定义的变量,注意不只是一级,如果上级没有会继续往上级找,直到找到为止,如果找到全局变量到找不到就会报错。
1 function a(){
2 var name = "追梦子";
3 function b(){
4 console.log(name); >> "追梦子"
5 }
6 b();
7 }
8 a();
3. 函数的另外一种调用形式,你可以把它叫做自调用,自己调用自己,达到自执行的效果。
1 var a = 0;
2 (function(){
3 console.log(++a); >>1
4 })()
这种方式用()把内容包裹起来,后面的()表示执行这个函数,可能你会问为什么要把函数包起来,如果不包裹起来,js会把它当作函数声明来处理,如果包裹起来就是表达式,还没有看懂就上网查吧。
开始我们正式闭包部分---------------------------- 币包 ---------------像钱包一样的东西,可以把东西包裹起来----------
首先我们来看看为什么需要学习闭包,加以理解 -- 0 v 0- -
1 function a(){
2 var num = 0;
3 console.log(++num);
4 }
5 a(); >>1
6 a(); >>1
上面代码输出了两次1,为什么呢?如果你有看我上面的关于变量部分肯定能够想到个大概。
前面我们说过了函数执行完以后,里面的变量(即局部变量)就会销毁,下一次运行又会重新创建那个变量,所以虽然你第一次++num了但是这个变量在第一次执行完毕以后就被销毁了。
那么我们怎么样才能确保第一次的变量不被销毁,那么就需要我们的闭包出场了。
温馨提示:JavaScript中有回收机制,函数没有被引用执行完以后这个函数的作用域就会被销毁,如果一个函数被其他变量引用,这个函数的作用域将不会被销毁,(简单来说就是函数里面的变量会被保存下来,你可以理解成全局变量。)
…………………………………………………………………………………… 当 当 当 ................. 下面有请我们的币包同志
function a(){
var aa = ;
function b(){
aa ++;
console.log(aa);
}
return b;
}
var ab = a();
ab(); //1
ab(); //2
看到了吧里面的变量的值没有被销毁,因为函数a被外部的变量ab引用,所以变量aa没有被回收。
如果某个函数被它的父函数之外的一个变量引用,就形成了一个闭包
还有一种更为常用的闭包写法
var bi = (function(){
var a = ;
function b(){
a ++;
console.log(a);
}
return b;
})();
bi(); //1
bi(); //2
bi(); //3
执行过程分析:
首先把一个自执行函数赋值给了bi,这个自执行函数运行完成以后就bi的值就变成了
function b(){
a ++;
console.log(a);
}
因为我们在上面的代码return回去了b,然后因为这个自执行函数被bi引用所以里面的变量a并没有因为这个自执行函数执完而销毁,而是保存到了内存中,所以我们多次打印bi()就成了1、2、3
下面我来说一个闭包的使用场景吧。
没有使用闭包的版本
window.onload = function(){
var ul = document.getElementsByTagName("ul")[0];
var li = ul.getElementsByTagName("li");
for(var i=0;i<li.length;i++){
li[i].onclick = function(){
console.log(i); //不管我怎么点都是返回
}
}
}
使用了闭包的版本
window.onload = function(){
var ul = document.getElementsByTagName("ul")[0];
var li = ul.getElementsByTagName("li");
for(var i=0;i<li.length;i++){
(function(i){
li[i].onclick = function(){
console.log(i); //点击第几个返回第几个
}
})(i)
}
}
、、、、、如果你不理解这个,你只要这样子用就能够达到效果。
这也只是简单的介绍了一下,后面将会在闭包的高级部分讲解。如果你对闭包有更深的理解可以pm我。
初识js中的闭包的更多相关文章
- 详解js中的闭包
前言 在js中,闭包是一个很重要又相当不容易完全理解的要点,网上关于讲解闭包的文章非常多,但是并不是非常容易读懂,在这里以<javascript高级程序设计>里面的理论为基础.用拆分的方式 ...
- js中的闭包之我理解
闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的 ...
- 浅谈JS中的闭包
浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...
- js中的“闭包”
js中的“闭包” 姓名:闭包 官方概念:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. ( ⊙o⊙ )!!!这个也太尼玛官方了撒,作为菜鸟的 ...
- JS中的闭包(closure)
JS中的闭包(closure) 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面就是我的学习笔记,对于Javascript初学者应该是很有用 ...
- Js中的闭包原理
要了解清楚js中的闭包制机,那么得先了解全局执行环境.块级执行环境.函数执行环境.变量对象.环境栈.作用域链.摧毁执行环境. 全局执行环境 全局执行环境指的是最外层的执行环境.在web中全局执行环境被 ...
- js中的闭包理解一
闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的 ...
- js中的闭包理解
闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的 ...
- 理解js中的闭包
闭包 我的理解是 能够有权访问另一个函数作用域中变量的函数 通常我们知道 普通的函数在调用完成之后,活动对象不会从内存中销毁,其执行环境的作用域链会被销毁,造成资源的浪费 而闭包的好处就在于执行完就会 ...
随机推荐
- JQ属性和css部分测试
1.attr(name|properties|key,value|fn) 设置或返回被选元素的属性值. <div class="attr">设置或返回被选元素的属性值 ...
- 几种web数据渲染模板对比
在web开发,实现视图.数据的分离,由前端工程师专门负责编写html页面,有php后台工程师写php接口返回json数字,那么中间如何将json数据绑定到html页面上有几种方法呢.基于这种需求大体上 ...
- $.ajax()方法解析
$.ajax()方法,在web网站开发中常用到,作为一种用于创建快速动态网页的技术(异步JavaScript和XML).通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新.这意味着可以 ...
- SDWebImage ReadMe.md文档简单说明
SDWebImage ReadMe.md 文档 附:SDWebImage框架github下载地址:https://github.com/rs/SDWebImage 注1:该文章简单翻译了SDWebIm ...
- ffmpeg mp3 to m3u8
ffmpeg -i Sunshine.mp3 -c:a libmp3lame -b:a 128k -map 0:0 -f segment -segment_time 10 -segment_list ...
- mysqld.exe 占了400M内存的问题
最近遇到了服务器总是停机的问题,虽然它自己只有2G的内存,不过实际部署的应用访问量非常小,也不至于2G就不够用,所以开始了给服务器瘦身的计划. 看着任务管理器里面的各个进程,发现吃内存最厉害的是mys ...
- js 生成笛卡尔积
其实生成 笛卡尔积的方法原本很简单,for循环就可以了, function discarts() { //笛卡尔积 var twodDscartes = function (a, b) { var r ...
- 不会用ant打包、部署项目的工程师,不是一个好程序员(测试)
副标题:利用ant脚本 自动构建svn增量/全量 系统程序升级包 首先请允许我这样说,作为开发或测试,你一定要具备这种本领.你可以手动打包.部署你的工程,但这不是最好的方法.最好的方式就是全自动化的方 ...
- Js 数据容量单位转换(kb,mb,gb,tb)
function bytesToSize(bytes) { if (bytes === 0) return '0 B'; var k = 1000, // or 1024 sizes = ['B', ...
- 查看Exchange邮件队列(queue)
#加载Exchange管理模块 Add-PSSnapin Microsoft.Exchange.Management.PowerShell.snapin get-queue #查看队列 get-mes ...