1、概念
闭包函数: 申明在一个函数中的函数,叫做闭包函数。
闭包: 外部函数总是能够拜访其所在的内部函数中申明的参数和变量,即便在其内部函数被返回(寿命终结)了之后。
2、特点
让内部拜访函数外部变量成为可能;
局部变量会常驻在内存中;
能够防止应用全局变量,避免全局变量净化;
会造成内存透露(有一块内存空间被长期占用,而不被开释)
3、闭包的创立:
闭包就是能够创立一个独立的环境,每个闭包外面的环境都是独立的,互不烦扰。闭包会产生内存透露, 每次内部函数执行的时 候,内部函数的援用地址不同,都会从新创立一个新的地址。 但但凡以后流动对象中有被外部子集援用的数据,那么这个时候,这个数据不删除,保留一根指针给外部流动对象。
闭包内存透露为:key = value,key 被删除了 value 常驻内存中; 局部变量闭包升级版(两头援用的变量)=> 自在变量;
4、闭包的利用场景
论断:闭包找到的是同一地址中父级函数中对应变量最终的值
最终秘诀就这一句话,每个例子请自行带入这个论断!!!!!!!!!!!!!
/ 例子 1 /
function funA(){
var a = 10; // funA 的流动对象之中;
return function(){ // 匿名函数的流动对象;
alert(a);
}
}
var b = funA();
b(); //10
/ 例子 2 /
function outerFn(){
var i = 0;
function innerFn(){
i++;
console.log(i);
}
return innerFn;
}
var inner = outerFn(); // 每次内部函数执行的时候, 都会开拓一块内存空间, 内部函数的地址不同,都会从新创立一个新的地址
inner();
inner();
inner();
var inner2 = outerFn();
inner2();
inner2();
inner2(); //1 2 3 1 2 3
/ 例子 3 /
var i = 0;
function outerFn(){function innnerFn(){
i++;
console.log(i);
}
return innnerFn;
}
var inner1 = outerFn();
var inner2 = outerFn();
inner1();
inner2();
inner1();
inner2(); //1 2 3 4
/ 例子 4 /
function fn(){
var a = 3;
return function(){return ++a;}
}
alert(fn()()); //4
alert(fn()()); //4
/ 例子 5 /
function outerFn(){
var i = 0;
function innnerFn(){
i++;
console.log(i);
}
return innnerFn;
}
var inner1 = outerFn();
var inner2 = outerFn();
inner1();
inner2();
inner1();
inner2(); //1 1 2 2
/ 例子 6 /
(function() {
var m = 0;
function getM() { return m;}
function seta(val) {m = val;}
window.g = getM;
window.f = seta;
})();
f(100);
console.info(g()); //100 闭包找到的是同一地址中父级函数中对应变量最终的值
/ 例子 7 /
function a() {
var i = 0;
function b() { alert(++i); }
return b;
}
var c = a();
c(); //1
c(); //2
/ 例子 8 /
function f() {
var count = 0;
return function() {
count++;
console.info(count);
}
}
var t1 = f();
t1(); //1
t1(); //2
t1(); //3
/ 例子 9 /
var add = function(x) {
var sum = 1;
var tmp = function(x) {
sum = sum + x;
return tmp;
}
tmp.toString = function() {return sum;}
return tmp;
}
alert(add(1)(2)(3)); //6
/ 例子 10 /
var lis = document.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){(function(i){lis[i].onclick = function(){console.log(i);
};
})(i); // 事件处理函数中闭包的写法
}
/ 例子 11 /
function m1(){
var x = 1;
return function(){console.log(++x);
}
}
m1()(); //2
m1()(); //2
m1()(); //2
var m2 = m1();
m2(); //2
m2(); //3
m2(); //4
/ 例子 12 /
var fn=(function(){
var i=10;
function fn(){console.log(++i);
}
return fn;
})()
fn(); //11
fn(); //12
/ 例子 13 /
function love1(){
var num = 223;
var me1 = function() {console.log(num);
}
num++;
return me1;
}
var loveme1 = love1();
loveme1(); // 输入 224
/ 例子 14 /
function fun(n,o) {console.log(o);
return {fun:function(m) {return fun(m,n);
}
};
}
var a = fun(0); //undefined
a.fun(1); //0
a.fun(2); //0
a.fun(3); //0
var b = fun(0).fun(1).fun(2).fun(3); //undefined 0 1 2
var c = fun(0).fun(1);
c.fun(2);
c.fun(3); //undefined 0 1 1
/ 例子 15 /
function fn(){var arr = [];
for(var i = 0;i < 5;i ++){arr[i] = function(){return i;}
}
return arr;
}
var list = fn();
for(var i = 0,len = list.length;i < len ; i ++){console.log(list[i]());
} //5 5 5 5 5
/ 例子 16 /
function fn(){var arr = [];
for(var i = 0;i < 5;i ++){arr[i] = (function(i){return function (){return i;};
})(i);
}
return arr;
}
var list = fn();
for(var i = 0,len = list.length;i < len ; i ++){console.log(list[i]());
} //0 1 2 3 4