共计 2778 个字符,预计需要花费 7 分钟才能阅读完成。
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 |
正文完
发表至: javascript
2020-09-22