我理解的闭包
// JS中的一个函数如果访问了外层的一个变量就会形成闭包
var sge=12;
function add(){
console.log(sge);//访问函数外部的变量就形成闭包
}
add()
function f(){
var name="zhangsan";
function s(){
console.log("abb",name);
}
return s;
}
var ff=f();
ff();





代码 function foo() {
var name = "foo"
var age = 18
function bar() {
console.log(name)
console.log(age)
}
return bar
}
var fn = foo()
fn()

<ul class="nav">
<li>打印index1</li>
<li>打印index2</li>
<li>打印index3</li>
<li>打印index4</li>
</ul>
<script>
// 1. 我们可以利用动态添加属性的方式
var lis = document.querySelector('.nav').querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
lis[i].index = i;
lis[i].onclick = function() {
// console.log(i);
console.log(this.index);
}
}
// 2. 利用闭包的方式得到当前小li 的索引号
for (var i = 0; i < lis.length; i++) {
// 利用for循环创建了4个立即执行函数
// 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它的i这变量
(function(i) {
// console.log(i);
lis[i].onclick = function() {
console.log(i);
}
})(i); //注意这里必须传递i
}
</script>
```javascript
<script>
var lis = document.querySelector('.nav').querySelectorAll('li');
// for (var i = 0; i < lis.length; i++) {
// setTimeout(function() {
// console.log(lis[i].innerHTML); //报错无法读取未定义的属性
// }, 3000)
// }
for (var i = 0; i < lis.length; i++) {
(function(i) {
setTimeout(function() {
console.log(lis[i].innerHTML);
}, 3000)
})(i) //必须要跟实参
}
</script>
优点:
缺点:

上面中我们为什么经常会说闭包是有内存泄露的呢?
那么,怎么解决这个问题呢?
因为当将add10设置为null时,就不再对函数对象0xb00有引用,那么对应的AO对象0x200也就不可达了;
在GC的下一次检测中,它们就会被销毁掉;

function f(){
var name="zhangsan";
var age=18;
function s(){ //指针?
console.log(name,age);
} //这里的s函数对象是指向f() 在函数执行完毕后A0不会被销毁 保存了下来
return s;
}
var obj=f();
obj();
obj=null // 指向空销毁内存空间
闭包的内存泄漏主要是指 :


测试代码
function createFnArray() {
// var arr = [1, 1, 1, 1, 1, 1, 1, 1,1, 1,1, 1,1 ]
// 占据的空间是4M x 100 + 其他的内存 = 400M+
// 1 -> number -> 8byte -> 8M
// js: 10 3.14 -> number -> 8byte ? js引擎
// 8byte => 2的64次方 => 4byte
// 小的数字类型, 在v8中成为Sim, 小数字 2的32次方
var arr = new Array(1024 * 1024).fill(1)
return function() {
console.log(arr.length)
}
}
// var arrayFn = createFnArray()
// arrayFn = null
// 100 * 100 = 10000 = 10s
var arrayFns = []
for (var i = 0; i < 100; i++) {
setTimeout(() => {
arrayFns.push(createFnArray())
}, i * 100);
}
// arrayFns = null
setTimeout(() => {
for (var i = 0; i < 50; i++) {
setTimeout(() => {
arrayFns.pop()
}, 100 * i);
}
}, 10000);