社区精选|深入剖析 JavaScript 闭包
今天小编为大家带来的是社区作者 程序员海军 的文章,让我们一起来深入剖析 JavaScript 闭包
导读目录
什么是闭包
闭包的特性
闭包的优缺点
闭包的作用
闭包的注意点
什么是闭包?
闭包的形成与变量的作用域以及变量的生存周期密切相关。
闭包的特性
函数嵌套函数 函数内部可以引用外部的参数和变量 参数和变量不会被垃圾回收机制回收
闭包的优缺点
关于变量
var a = '闭包';
function getValue(){
var a = '函数局部作用域'
console.log(a)
}
getValue() //函数局部作用域
函数作用域
在函数内部可以访问到函数外部变量,而在函数外部的变量不可以访问函数内部的变量。
为什么呢?
function getData() {
var str = "闭包练习";
var fun = function(){
var innerStr = '内部变量'
}
console.log(innerStr)
//innerStr is not defined 函数外层是访问不到 函数内层变量的
}
getData()
变量的生存周期
<!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>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<script>
var nodes = document.getElementsByTagName('div')
for (var i = 0; i < nodes.length; i++) {
nodes[i].onclick = function () {
alert(i)
}
}
</script>
</body>
</html>
为什么呢?
如何解决点击每个 div 弹出对应的 i 值呢 ?
# 闭包解决办法
<script>
var nodes = document.getElementsByTagName('div')
for (var i = 0; i < nodes.length; i++) {
(function(i) {
nodes[i].onclick = function () {
alert(i)
}
})(i)
}
</script>
栗子 2
var num = 1;
function getValue(){
var num = 0;
return function(){
num++
console.log(num)
}
}
var s = getValue()
s()
s()
// 1 2
var num = 1;
function getValue(){
var num = 0;
return function(){
num++
console.log(num)
}
}
getValue()()
getValue()()
// 0 0
闭包的作用
闭包的注意作用为这两项:
可以读取函数内部的变量 可以变量的值始终保持在内存中
栗子
function f2(){
let num = 0;
addNum = function(){
num++
}
function f3(){
console.log(num)
}
return f3
}
var a = f2()
a()
addNum()
a()
// 0 1
结果为 0 1
第一次 执行 a() 时, 结果为 0 , 很好理解。
第二次 执行的 f2() 函数内部的 addNum 函数,发现没这个匿名函数赋值给一个变量,而且这个变量没加 var / let , 那么它此时的作用域为 全局 ,保存在内存当中。执行 addNum 时它访问的 f2() 函数内部的局部变量 num , 此时, addNum 的存在依赖于 f2,因此 f2 也在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
第三此 执行 a() 时, 因为 num 已存在内存中,而至值为1
闭包注意
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
-
JavaScript 未必是最优选,下一代浏览器语言会是什么样?
【CSDN 编者按】提及前端,JavaScript 是一门避不开的编程语言。不过在浏览器领域,本文作者认为直接使用 JavaScript 未必是最佳选择,同时在开发过程中,使用编译为 WebAssem
-
SegmentFault 思否技术周刊 — 如何有效地学习 JavaScript ?
本期技术周刊一起了解 Javascript,欢迎大家阅读 ~文章推荐手写一个同步服务端时间的小工具 作者:jump__jump在前端开发的过程中,开发者经常会用到 new Date() 来获取当前时间
-
用 20+ 行 JavaScript 代码,短暂“变身” iOS 程序员!
摘要:你有没有尝试过在 iOS 中创建小部件,感受一把身为 iOS 程序员的快乐?本文作者将用二十几行 JavaScript 代码教你构建一个 iOS 小部件,据他所说,这“一点都不难”。原文链接:h
关注公众号:拾黑(shiheibook)了解更多
赞助链接:
关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 【新春走基层】智能工厂增产忙
- 【杂谈快报】12月13日0时起,通信行程卡正式下线;微软收购动视暴雪遇阻,监管机构不同意
- 安全智能,全栈自主!统信「信息发布终端」解决方案亮相
- 上市公司改名,科学还是玄学?
- MIT 曝光 M1 不可修复的漏洞,网友:时间挺巧,是时候换 M2 了!
- 《你名下有几张电话卡》查询服务正式发布,可通过微信、支付宝查询
- 手机散热背夹横评:红魔VS黑鲨,都是179元买谁才不亏?
- 芯片制造,欧洲日本为何执着于2纳米?
- 去年免费播《囧妈》后,今年抖音独家合作七部春节档大片
- 身边噪音烟消云散,三款颈挂式降噪蓝牙耳机推荐
- 【大公司创新情报】宁德时代对三个锂离子电池基地进行项目投资
- OPPO Reno5选择此时上线,不是好时机?