还在为JS闭包烦恼? FF带你一篇文章玩转闭包,某化腾听了都说好!!
下定义喽!
闭包:能够读取其他函数变量的函数(源自某度)。但这不是唯一答案,当你明白闭包究竟是什么后,你会发现每个人对于闭包的定义都不同。
我认为:闭包就是一对函数嵌套,且外层嵌套将内层嵌套函数返回到外层嵌套函数的外部,这就是闭包。
我们举一个例子:
function foo(){var a=0;return ()=>{var b=a; console.log(b)}
}let foo1=foo();foo1();
大家看,foo1()的结果是什么呢? 很明显,最后输出的结果是0。如果你不懂闭包可能会很疑惑,foo函数内部的变量怎么能在外部被访问呢,这就是闭包的作用,可以使你访问到局部作用域中的变量。
我们再来看一个初学者都很容易犯得一个错误,大家一定都学过事件绑定吧,请大家看我接下来所写的一段代码。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><h1>hello world</h1><h1>hello world</h1><h1>hello world</h1>
</body>
<script>var h1List = document.querySelectorAll('h1');for (var i = 0; i < h1List.length; i++) {h1List[i].onmouseenter = function () {h1List[i].style.backgroundColor = 'red';}h1List[i].onmouseout = function () {h1List[i].style.backgroundColor = '';}}
</script></html>
大家感觉这些代码可以事件我鼠标移入h1后让h1变色,在鼠标移出后背景色清除呢?如果你觉得能够实现的话,同学,我建议你再去亲自写一遍尝试一下。很明显这段代码并不能实现我们的需求,你自己尝试后会发现你鼠标移入之后,控制到会报下边这种错误:如下图:
这个报错是什么意思呢?"不能从undefined这个属性上读取style这个属性",很明显,这时候的h1List[i] 的值变成了undefined ,这时候你可能就有了疑惑,这是怎么回事呢,h1List[i] 中的i不是一直跟随着循环中的 i 变化吗?不应该是 0,1 ,2吗,如果你能自己弄懂这样一个问题,那么恭喜你,你已经打败了全国百分之80的初级程序员了。下面让我来为大家解答:
首先,大家需要弄清楚,程序的执行分为同步执行与异步执行, 而在上面我们所写的for循环就是一段同步代码,在代码执行时,他会迅速的执行完毕,对他当中的 i 变量进行四次赋值,前三次分别是0,1,2,到最后一次i++时发现结果等于3,不小于h1List 的长度,跳出循环。这是由于 i 是由var声明的变量,所以 i 可以在for循环中被随意的访问和修改,最终 i 的值变成了4,
第二,你肯定知道我们绑定的事件处理函数,是属于异步程序,只有你达到了该函数的执行条件他才会触发,所以在你触发事件时,函数中的 i 早已被修改成了4,所以这就是导致报错的原因。也就是由于 变量污染 导致的。那我们要怎么解决它呢?这时候就要由我们的闭包出场了!!
var h1List = document.querySelectorAll('h1');for (var i = 0; i < h1List.length; i++) {(function (i) {h1List[i].onmouseenter = function () {h1List[i].style.backgroundColor = 'red';}h1List[i].onmouseout = function () {h1List[i].style.backgroundColor = '';}})(i)}
大家看,我在事件函数的外部添加了一个立即执行函数,众所周知,立即执行函数在代码执行到时会立刻执行,并在执行后生成一个自己的AO,来保存传入的形参 i ,并且每一个AO之间互不影响
如图:
上边的三个蛋,就代表for循环循环3次,立即执行函数创建的3个AO,它们彼此相互独立,互不影响,这时候你事件执行时,他就会在自己的AO内来寻找相对应的 i ,这样就可以避免 造成变量污染的问题。这就是闭包的作用。
总结:
闭包的优缺点:
优点:
1,创建一个安全的环境,保证内部代码不受到外部的干涉,(实现私有成员,对外只暴露几个接口)
2,让父函数中变量的值始终保存在内存中。
缺点:
1,内存消耗大,IE容易造成内存泄露
2,函数调用完手动回收变量!
还在为JS闭包烦恼? FF带你一篇文章玩转闭包,某化腾听了都说好!!相关推荐
- js层级选择框样式_IOS和JS的交互,看这一篇文章就够了
IOS和JS的交互,看这一篇文章就够了 创作不易,请珍惜,之后会持续更新,不断完善 Demo地址 目录 WKWebView使用.JS的交互 WKWebView使用.JS的交互 演示(本来想贴张GIF作 ...
- pandas输出到excel_学Python还不会处理Excel数据?带你用pandas玩转各种数据处理
开场白 以前学习 Python 的 pandas 包时,经常到一些 excel 的论坛寻找实战机会.接下来我会陆续把相关案例分享出来,还会把其中的技术要点做详细的讲解. 本文要点: 使用 xlwing ...
- 你真的认为自己熟练Python?带你一篇文章 查漏补缺,感受自己离深入掌握 Python 还有多远。
1. 模块化编程思想 模块化编程是 Python 的基本思想.初学 Python,都应该使用过小海龟.随机.数学模块.使用模块之前,需要导入模块,然后根据自己的问题需要使用这些模块. Python 提 ...
- 一篇文章带你详解 TCP/IP 协议(下)
前面的第一二三章已在上篇讲解,还没看过的可以先看看:一篇文章带你详解 TCP/IP 协议(上) 本文继续讲解第四章. 四.网络层中的 IP 协议 IP(IPv4.IPv6)相当于 OSI 参考模型中的 ...
- 你不懂JS:作用域与闭包 第五章:作用域闭包
希望我们是带着对作用域工作方式的健全,坚实的理解来到这里的. 我们将我们的注意力转向这个语言中一个重要到不可思议,但是一直难以捉摸的,几乎是神话般的 部分:闭包.如果你至此一直跟随着我们关于词法作用域 ...
- JS进阶笔记(原型、继承、this指向、闭包、递归、正则表达式)
文章目录 1.构造函数.实例对象.原型对象三者之间的关系 2.原型链 2.1.JS成员查找机制 2.2.原型对象中的this指向 2.3.利用原型对象扩展内置对象方法 3.继承 3.1 call方法的 ...
- html 下拉列表 模糊查询,JS实现模糊查询带下拉匹配效果
"搜索"可以使我们更快的找到某一个关键词或者某一个商品,所以"模糊查询"和"下拉匹配"也成了前端必备的一个小技能,开门见山,希望对朋友们有帮 ...
- z7D3 安装linux,还在为装系统烦恼?战神Z7-SL7D3为你轻松搞定
原标题:还在为装系统烦恼?战神Z7-SL7D3为你轻松搞定 一般情况下,如果更换电脑或是电脑系统出现问题,按照一般路径,都需要采用重装系统的方法来解决.虽然重装系统会让电脑的性能散发出全新的活力,可是 ...
- js new Date()不带时分秒时,时间变了 问题解决
js new Date()不带时分秒时,时间变了 问题解决 参考文章: (1)js new Date()不带时分秒时,时间变了 问题解决 (2)https://www.cnblogs.com/q149 ...
- 魅族15无法连接计算机,还在为数据丢失而烦恼?魅族15告诉你什么叫做碎屏无忧...
原标题:还在为数据丢失而烦恼?魅族15告诉你什么叫做碎屏无忧 无论是时下大热的"全面屏"技术或是"刘海屏"手机,他们都有着一个共同的特征:超高的屏占比.在为用户 ...
最新文章
- 这个医疗AI准确率突破天际,招来了铺天盖地的质疑
- linux shell which 和 whereis 区别
- sqlserver计算时间差DATEDIFF 函数
- opencv 检测 键盘_ubuntu+vscode 测试运行opencv
- leetcode 530. 二叉搜索树的最小绝对差(Java版)
- throw 烦人_烦人的简单句子聚类
- 通过hashtable实现dic
- 扎心!全国6.5亿网民月收入不足5000元
- 重拾阅读--朝花夕拾啊
- fckeditor 中文乱码问题
- java 构造器(constructor)是否可被重写(override)?
- java中的递归算法_java递归算法详解
- 【转】drpic在线图片处理器
- 美图秀秀各插件适用场景
- win7无权限连接网络计算机,win7系统出现无权限访问网络的完美解决技巧
- 跳过H5页面视频的方法
- Webshell的预防措施
- Micheal Jackson 离开了我们
- 五笔中三个字的词组打法
- 获得淘系商品详情展示
热门文章
- 网易免费邮箱服务器,网易免费邮箱重新免费开放 POP3/SMTP 服务
- 【leetcode】189.旋转数组 (四种方法开阔思路,java实现!)
- 【概率论】【笔记】【@汤家凤】【数一】【第五章】
- 09-01-28 自助装机
- Asp.net页面跳转的方法
- android studio静态界面设计,2.3 使用Android Studio 简单设计UI界面
- 计算机word打开,电脑word打不开怎么办
- 计算机导论结业报告大一,河北工业大学计算机导论结业论文
- 双目相机标定Matlab
- 服务器端查看图片库 eog display Xforwarding