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 = 0;
function b(){
aa ++;
console.log(aa);
}
return b;
}
var ab = a();
ab(); //1
ab(); //2
看到了吧里面的变量的值没有被销毁,因为函数a被外部的变量ab引用,所以变量aa没有被回收。
如果某个函数被它的父函数之外的一个变量引用,就形成了一个闭包
还有一种更为常用的闭包写法
var bi = (function(){
var a = 0;
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); //不管我怎么点都是返回6
}
}
}
使用了闭包的版本
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中闭包的理解
1.以前很不理解js中闭包的概念及使用,下面来看一下 function foo() { var a = 123; var b = 456; return function () { return a; ...
- js的闭包
一,关于js闭包的只是感觉很高大上似乎,对于学弱来说任何问题都是这样的,值得去钻研和提高. 资料上理解的都是关于js的闭包其实就是js的变量的作用域的灵活使用. 函数内部定义变量的时候,一定要用 va ...
- 彻底搞清js中闭包(Closure)的概念
js中闭包这个概念对于初学js的同学来说, 会比较陌生, 有些难以理解, 理解起来非常模糊. 今天就和大家一起来探讨一下这个玩意. 相信大家在看完后, 心中的迷惑会迎然而解. 闭包概念: 闭包就是有权 ...
- 理解运用JS的闭包、高阶函数、柯里化
JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...
- JS的闭包、高阶函数、柯里化
本文原链接:https://cloud.tencent.com/developer/article/1326958 https://cloud.tencent.com/developer/articl ...
- 关于js的闭包和复制对象
一.有关js的闭包 1.概念:所谓的闭包,就是指的两个作用域,其中内层作用于可以访问外层作用域的函数的现象 2.简单应用 for(var i = 0;i< lis.lenth;i++){ (fu ...
- JS的闭包问题
1.什么是“闭包” 是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 2.闭包的应用场景 (1)保护变量的安全实现JS私有属性和私有方法 (2)在 ...
- 深入理解JS的闭包
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...
- js的闭包概念
一.变量的作用域要懂得闭包,起首必须懂得Javascript特别的变量作用域.变量的作用域无非就是两种:全局变量和局部变量.Javascript说话的特别之处,就在于函数内部可以直接读取全局变量. J ...
随机推荐
- (转)as3效率优化
1.改进算法无论对于那一种程序,好的算法总是非常重要的,而且能够极大地提高程序性能,所以任何性能的优化第一步就是从算法或者说程序逻辑的优化开始,检查自己的程序是否有多余的运算,是否在没有必要的时候做了 ...
- Optimizely:在线网站A/B测试平台
Optimizely:在线网站A/B测试平台是一家提供 A/B 测试服务的公司.A/B 测试能够对比不同版本的设计,选取更吸引用户眼球的那一款,从而带来更为优化的个人体验.让网站所有者易于对不同版本的 ...
- CSS重新认识(一)
1. 所有的元素都遵循盒子模型,即内容部分+padding(填充部分)+border+margin(外边距部分); 2.我们平常定义的width与height指的内容部分的长宽; 3. 行内元素在不改 ...
- c#面向对象基础 重写、虚方法、抽象类
虚方法 抽象类与抽象方法 1.书写规范: 在类前面加上abstract关键字,就成为了抽象类:在一个方法前面加上abstract关键字,就成为了抽象方法(抽象方法不能有实现方法,直接在后面加分号) 例 ...
- Iconfont矢量图标平台全面升级
阿里UX矢量图标库今天全新发布上线了,这次升级相对于老版本做了30多项功能和体验上的改善:赶快来体验一下吧!! 请猛戳:www.iconfont.cn 请猛戳:www.iconfont.cn 设计师p ...
- NY-字符串替换
描述编写一个程序实现将字符串中的所有"you"替换成"we" 输入 输入包含多行数据 每行数据是一个字符串,长度不超过1000 数据以EOF结束 输出 对于输入 ...
- Mongodb数据库加密存储(python)
需求: 不知道大家有没有遇到过这样的需求:自己的服务器出于对数据库安全的保护,需要对存储的数据进行加密保护.这样万一数据库被人拿到,别人也不能拿到数据库里面的内容.这里还有一个前提:前端的展示页面是 ...
- IOS第14天(1,UITabBarController的基本的使用)
**************HMAppDelegate.m - (BOOL)application:(UIApplication *)application didFinishLaunchingWit ...
- Color Space: HSI
HSI色彩空间是从人的视觉系统出发,用色调(Hue).色饱和度(Saturation或Chroma)和亮度 (Intensity或Brightness)来描述色彩.HSI色彩空间可以用一个圆锥空间模型 ...
- 示例-创建表格-指定行列&删除表格的行和列
<body> <script type="text/javascript"> /* *上面的方法和你麻烦. *既然操作的是表格, *那么最方便的方式就是使用 ...