一、什么是闭包
GC 垃圾回收
通常情况下,函数被调用后,内部的变量 会自动回收,不用的变量 内存自动释放
特殊情况下,例函数里的变量 还会被 用到的就不会被回收 例: 3按钮 点击按钮 弹出 索引+1
1. 闭包的底层:栈
计算机 每调用一次函数时,内存就会 在内存中开辟一块空间,这个空间叫栈
整个函数的所有局部变量都在这个栈中运行
栈的本质:函数执行时会分配空间,函数结束时会回收
闭包可以做到的是:函数执行完了,栈也不回收,这就叫闭包
2.把函数当作对象处理
对于某些语言来说,例java,不能存在独立的方法,一定是寄存在某个对象上,不管是静态的动态的,而js不一样,js中有独立存在的函数,只要函数调用时,它就会创建一个对象出来,这个对象就包含函数的各种细节
function show(){
let a=12;
document.onclick=function(){
alert(a);
}
}
二、闭包的优缺点
闭包的好处:
延展了函数的局部作用域 的生命周期
正常情况下,一个函数被调用后,它的作用域 就会被销毁;
但当有闭包的情况时,局部作用域暂时不会销毁
闭包的缺点:
不能立即释放作用域,销毁局部作用域
三、产生闭包的几种情况
闭包是一个函数,可以访问独立数据的函数,
在一个作用域中可以访问另一个作用域的变量或者函数(嵌套的函数 访问了它外部的变量!!! (也可以是函数)
访问的外部函数是匿名函数时,Closure: 没有名字的函数)
function fn() { var n = 10; return n; }
fn();
发生闭包: 函数作为返回值
1.实例:获取1-10的随机数
function getRandom(){
var random = parseInt(Math.random()*10) + 1;
return function(){
return random;
}
}
var fn = getRandom();
console.log(fn());
2.实例:计算两个数的和
function getSum(n){
return function(m){
return n + m;
}
}
var fn = getSum(100);
var fn1000 = getSum(1000);
console.log(fn(1));
console.log(fn1000(1));
3.实例:点击ul下的li,打印li对应的索引值
var heros = document.getElementById('heros');
var list = heros.children;
for (var i = 0; i < list.length; i++) {
var li = list[i];
li.index = i;
li.onclick = function () {
console.log(this.index);
}
}
var heros = document.getElementById('heros');
var list = heros.children;
for (var i = 0; i < list.length; i++) {
var li = list[i];
(function(i){
li.onclick = function () {
console.log(i);
}
})(i)
}
4.实例:当for循环遇到定时器
console.log('start');
for(var i = 0; i < 3; i++) {
setTimeout(function(){
console.log(i);
},0)
}
console.log('over');
console.log('start');
for(var i = 0; i < 3; i++) {
(function(i){
setTimeout(function(){
console.log(i);
},0)
})(i)
}
console.log('over');
5.实例:点击相应按钮i,字体变化
var btn01 = document.getElementById('btn01');
var btn03 = document.getElementById('btn02');
var btn03 = document.getElementById('btn03');
btn01.onclick = function(){ document.body.style.fontSize = '12px';}
btn02.onclick = function(){ document.body.style.fontSize = '14px';}
btn03.onclick = function(){ document.body.style.fontSize = '16px';}
var btn01 = document.getElementById('btn01');
var btn03 = document.getElementById('btn02');
var btn03 = document.getElementById('btn03');
function makeFun(size){
return function(){
document.body.style.fontSize = size +'px';
} }
btn01.onclick = makeFun(12);
btn02.onclick = makeFun(14);
btn03.onclick = makeFun(16);
<div id="box">
<button size="12">按钮1</button>
<button size="14">按钮2</button>
<button size="16">按钮3</button>
</div>
function makeFun(size) {
return function () {
document.body.style.fontSize = size + 'px';
}
}
var box = document.getElementById('box');
var buttons = box.children;
for (var i = 0; i < buttons.length; i++) {
var btn = buttons[i];
var size = btn.getAttribute('size');
btn.onclick = makeFun(size);
}
四、定时器是如何工作的?
console.log('start');
setTimeout(function(){
console.log('timeout');
},0)
console.log('over');