閉包,看這一篇就夠了——帶你看透閉包的本質,百發百中
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
相關文章
- 原生JS之還原閉包的本質JS
- Git 看這一篇就夠了Git
- 索引?看這一篇就夠了!索引
- Transformer 看這一篇就夠了ORM
- MySQL,你只需看這一篇文章就夠了!MySql
- Flutter DataTable 看這一篇就夠了Flutter
- Java 集合看這一篇就夠了Java
- 代理模式看這一篇就夠了模式
- 學Mybatis,入門看這一篇就夠你學的了!MyBatis
- 數字貨幣錢包怎麼選?看這一篇就夠了!|幣評君
- 【集合論】關係閉包 ( 關係閉包求法 | 關係圖求閉包 | 關係矩陣求閉包 | 閉包運算與關係性質 | 閉包複合運算 )矩陣
- Elasticsearch入門,看這一篇就夠了Elasticsearch
- 關於SwiftUI,看這一篇就夠了SwiftUI
- 瞭解 MongoDB 看這一篇就夠了MongoDB
- flex佈局看這一篇就夠了Flex
- ActiveMq 之JMS 看這一篇就夠了MQ
- MySQL入門看這一篇就夠了MySql
- jQuery入門看這一篇就夠了jQuery
- 入門Hbase,看這一篇就夠了
- Spring入門看這一篇就夠了Spring
- Mybatis入門看這一篇就夠了MyBatis
- Python操作MongoDB看這一篇就夠了PythonMongoDB
- IDEA中的Git操作,看這一篇就夠了!IdeaGit
- Python快速入門,看這一篇就夠了!Python
- Android Architecture Components 只看這一篇就夠了Android
- Git讓你從入門到精通,看這一篇就夠了!Git
- 關於Scrum敏捷開發,只看這一篇就夠了!Scrum敏捷
- 封閉了內心卻包容了天下,閉包你並不孤獨
- 熱門好用的api大全,看這一篇就夠了API
- Spring中的BeanFactory與FactoryBean看這一篇就夠了SpringBean
- 想要告警的智慧化管理?看這一篇就夠了
- 瞭解Java中的鎖,看這一篇就夠了!Java
- Python字串的格式化,看這一篇就夠了Python字串
- 閉包
- 瞭解SSL證書,看這一篇就夠了!!
- Nginx 配置常用引數,看這一篇就夠了Nginx
- SpringBoot寫後端介面,看這一篇就夠了!Spring Boot後端
- 什麼是事件管理?看這一篇就夠了!事件