国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

關于JavaScript閉包的應用

開發 前端
閉包就是指有權訪問另一個函數作用域中的變量的函數。MDN 上面這么說:閉包是一種特殊的對象。它由兩部分構成:函數,以及創建該函數的環境。環境由閉包創建時在作用域中的任何局部變量組成。創建閉包最常見方式,就是在一個函數內部創建另一個函數。

[[171507]]

什么是閉包(Closure)

簡單講,閉包就是指有權訪問另一個函數作用域中的變量的函數。

MDN 上面這么說:閉包是一種特殊的對象。它由兩部分構成:函數,以及創建該函數的環境。環境由閉包創建時在作用域中的任何局部變量組成。

但是,網上找了好多資料,它們對閉包的定義也各有各樣,搞得我也不知道怎么去定義閉包了,所以干脆不去定義了,意會吧。

道可道,非常道;名可名,非常名。

產生一個閉包

創建閉包最常見方式,就是在一個函數內部創建另一個函數。下面例子中的 closure 就是一個閉包:

  1. function func(){ 
  2.   var a = 1,b = 2; 
  3.    
  4.   function closure(){ 
  5.     return a+b; 
  6.   } 
  7.   return closure; 
  8.  

閉包的作用域鏈包含著它自己的作用域,以及包含它的函數的作用域和全局作用域。

閉包的注意事項

通常,函數的作用域及其所有變量都會在函數執行結束后被銷毀。但是,在創建了一個閉包以后,這個函數的作用域就會一直保存到閉包不存在為止。

  1. function makeAdder(x) { 
  2.   return function(y) { 
  3.     return x + y; 
  4.   }; 
  5.  
  6. var add5 = makeAdder(5); 
  7. var add10 = makeAdder(10); 
  8.  
  9. console.log(add5(2));  // 7 
  10. console.log(add10(2)); // 12 
  11.  
  12. // 釋放對閉包的引用 
  13. add5 = null
  14. add10 = null 

add5 和 add10 都是閉包。它們共享相同的函數定義,但是保存了不同的環境。在 add5 的環境中,x 為 5。而在 add10 中,x 則為 10。***通過 null 釋放了 add5 和 add10 對閉包的引用。

在javascript中,如果一個對象不再被引用,那么這個對象就會被垃圾回收機制回收;

如果兩個對象互相引用,而不再被第3者所引用,那么這兩個互相引用的對象也會被回收。

閉包只能取得包含函數中任何變量的***一個值,這是因為閉包所保存的是整個變量對象,而不是某個特殊的變量。

  1. function test(){ 
  2.   var arr = []; 
  3.   for(var i = 0;i < 10;i++){ 
  4.     arr[i] = function(){ 
  5.       return i; 
  6.     }; 
  7.   } 
  8.   for(var a = 0;a < 10;a++){ 
  9.     console.log(arr[a]()); 
  10.   } 
  11. test(); // 連續打印 10 個 10  

對于上面的情況,如果我們改變代碼如下:

  1. function test(){ 
  2.   var arr = []; 
  3.   for(let i = 0;i < 10;i++){  // 僅在這里作出了改動 
  4.     arr[i] = function(){ 
  5.       return i; 
  6.     }; 
  7.   } 
  8.   for(var a = 0;a < 10;a++){ 
  9.     console.log(arr[a]()); 
  10.   } 
  11. test(); // 打印 0 到 9  

對于上面兩種代碼的解釋,請看我在 segmentfault 上面的提問:鏈接

閉包中的 this 對象

  1. var name = "The Window"
  2.  
  3. var obj = { 
  4.   name"My Object"
  5.    
  6.   getName: function(){ 
  7.     return function(){ 
  8.       return this.name
  9.     }; 
  10.   } 
  11. }; 
  12.  
  13. console.log(obj.getName()());  // The Window  

obj.getName()()實際上是在全局作用域中調用了匿名函數,this指向了window。這里要理解函數名與函數功能(或者稱函數值)是分割開的,不要認為函數在哪里,其內部的this就指向哪里。匿名函數的執行環境具有全局性,因此其 this 對象通常指向 window。 

  1. var name = "The Window"
  2.  
  3. var obj = { 
  4.   name"My Object"
  5.    
  6.   getName: function(){ 
  7.     var that = this; 
  8.     return function(){ 
  9.       return that.name
  10.     }; 
  11.   } 
  12. }; 
  13.  
  14. console.log(obj.getName()());  // My Object  

閉包的應用

應用閉包的主要場合是:設計私有的方法和變量。

任何在函數中定義的變量,都可以認為是私有變量,因為不能在函數外部訪問這些變量。私有變量包括函數的參數、局部變量和函數內定義的其他函數。

把有權訪問私有變量的公有方法稱為特權方法(privileged method)。

  1. function Animal(){ 
  2.    
  3.   // 私有變量 
  4.   var series = "哺乳動物"
  5.   function run(){ 
  6.     console.log("Run!!!"); 
  7.   } 
  8.    
  9.   // 特權方法 
  10.   this.getSeries = function(){ 
  11.     return series; 
  12.   }; 
  13.  

模塊模式(The Module Pattern):為單例創建私有變量和方法。

單例(singleton):指的是只有一個實例的對象。JavaScript 一般以對象字面量的方式來創建一個單例對象。

  1. var singleton = { 
  2.   name"percy"
  3.   speak:function(){ 
  4.     console.log("speaking!!!"); 
  5.   }, 
  6.   getName: function(){ 
  7.     return this.name
  8.   } 
  9. };  

上面是普通模式創建的單例,下面使用模塊模式創建單例:

  1. var singleton = (function(){ 
  2.    
  3.   // 私有變量 
  4.   var age = 22; 
  5.   var speak = function(){ 
  6.     console.log("speaking!!!"); 
  7.   }; 
  8.    
  9.   // 特權(或公有)屬性和方法 
  10.   return { 
  11.     name"percy"
  12.     getAge: function(){ 
  13.       return age; 
  14.     } 
  15.   }; 
  16. })();  

匿名函數***的用途是創建閉包,并且還可以構建命名空間,以減少全局變量的使用。從而使用閉包模塊化代碼,減少全局變量的污染。

  1. var objEvent = objEvent || {}; 
  2. (function(){  
  3.     var addEvent = function(){  
  4.       // some code 
  5.     }; 
  6.     function removeEvent(){ 
  7.       // some code 
  8.     } 
  9.  
  10.     objEvent.addEvent = addEvent; 
  11.     objEvent.removeEvent = removeEvent; 
  12. })();  

在這段代碼中函數 addEvent 和 removeEvent 都是局部變量,但我們可以通過全局變量 objEvent 使用它,這就大大減少了全局變量的使用,增強了網頁的安全性。

一個閉包計數器 

  1. var countNumber = (function(){ 
  2.   var num = 0; 
  3.   return function(){ 
  4.     return ++num; 
  5.   }; 
  6. })();  

閉包的缺陷

  • 閉包的缺點就是常駐內存會增大內存使用量,并且使用不當很容易造成內存泄露。
  • 如果不是因為某些特殊任務而需要閉包,在沒有必要的情況下,在其它函數中創建函數是不明智的,因為閉包對腳本性能具有負面影響,包括處理速度和內存消耗。

***再來一些有關閉包的面試題

下面代碼中,標記 ? 的地方輸出分別是什么?

  1. function fun(n,o){ 
  2.   console.log(o); 
  3.   return { 
  4.     fun: function(m){ 
  5.       return fun(m,n); 
  6.     } 
  7.   }; 
  8.  
  9. var a = fun(0);  // ? 
  10. a.fun(1);        // ?         
  11. a.fun(2);        // ? 
  12. a.fun(3);        // ? 
  13.  
  14. var b = fun(0).fun(1).fun(2).fun(3);  // ? 
  15.  
  16. var c = fun(0).fun(1);  // ? 
  17. c.fun(2);        // ? 
  18. c.fun(3);        // ?  
  1. undefined 
  2. undefined, 0, 1, 2 
  3. undefined, 0 
  4.  

參考資料

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2021-02-21 16:21:19

JavaScript閉包前端

2023-09-06 16:55:33

JavaScript閉包

2020-02-12 16:58:15

JavaScript前端技術

2009-07-24 17:30:37

Javascript閉

2020-10-14 15:15:28

JavaScript(

2011-05-25 14:48:33

Javascript閉包

2023-11-26 00:34:36

Javascript應用方法

2012-11-29 10:09:23

Javascript閉包

2016-09-18 20:53:16

JavaScript閉包前端

2010-06-23 10:24:42

Javascript閉

2021-05-28 07:12:59

Python閉包函數

2017-09-14 13:55:57

JavaScript

2011-03-02 12:33:00

JavaScript

2011-05-12 18:26:08

Javascript作用域

2010-06-29 08:39:25

Python閉包

2021-12-06 07:15:48

Javascript作用域閉包

2017-05-22 16:08:30

前端開發javascript閉包

2009-03-17 15:36:29

JavaScript循環事件

2021-01-13 11:25:12

JavaScript閉包函數

2011-08-24 17:09:35

LUA閉包函數
點贊
收藏

51CTO技術棧公眾號

91精品黄色| 九色丨porny丨| 久久久久九九精品影院| 岛国av一区二区三区| 国产综合动作在线观看| 成人av综合网| 精品国产乱码久久久久久闺蜜| 91黑丝在线| 国产jizzjizz一区二区| 91在线免费视频| 97久久精品| 国产视频一区在线| wwwxxx在线观看| 国产片侵犯亲女视频播放| 日韩有码av| 中文字幕精品在线| 免费网站看v片在线a| 亚洲成人av中文| 国产成人久久777777| 久久一区二区三区超碰国产精品| 欧美在线国产精品| 国产剧情一区二区在线观看| 精品国产1区二区| 岛国在线视频| 亚洲亚洲人成综合网络| 999精品网站| 国产99精品国产| 手机成人在线| 99国产精品私拍| 亚洲综合中文字幕在线| 超碰成人久久| 日本高清视频一区| 久久久久九九精品影院| 深夜福利日韩在线看| 日韩精品av| 亚洲精品www久久久| www.久久久久.com| 666欧美在线视频| 色网站免费在线观看| 日本韩国一区二区三区视频| 亚洲欧洲成人| 欧美色视频日本版| 黑人与亚洲人色ⅹvideos| 欧美丝袜一区二区三区| 日韩私人影院| 91久久精品网| 好操啊在线观看免费视频| 欧美三级日韩在线| 久久国产精品一区| 日韩一区二区在线免费观看| 中文字幕免费高清电视剧网站在线观看 | 欧美这里有精品| 性欧美精品孕妇| 欧美午夜精品伦理| 高清国产福利在线观看| 欧美体内she精视频在线观看| 97精品国产97久久久久久免费| 日韩在线观看中文字幕| 欧美日韩国产成人在线观看| 成人高潮视频| 国产日韩欧美黄色| 亚洲激情亚洲| 亚洲三区在线| 久久先锋资源网| 国产激情视频网址| 欧美影院一区二区三区| а√天堂中文资源在线bt| 99国内精品久久| www.亚洲天堂网| 一区二区三区中文在线观看| 日韩电影在线观看完整版| 欧美一级片免费看| 欧美艳星kaydenkross| 欧美日本在线视频中文字字幕| 羞羞色国产精品网站| 欧美一乱一性一交一视频| 99久久99视频只有精品| 日韩欧美一区二区视频在线播放| 成人听书哪个软件好| av网站观看| 欧美日韩一级视频| 日本电影久久久| 国产精品视频白浆免费视频| 亚洲一级在线| 精品久久久久久久免费人妻| 欧美日韩国内自拍| 婷婷电影在线观看| 全亚洲最色的网站在线观看| 国产精品最新自拍| 色悠悠久久综合网| 欧美裸体一区二区三区| 精品视频在线观看免费观看 | 欧美色图12p| 成人啊v在线| 国产日韩欧美夫妻视频在线观看 | 日日夜夜亚洲精品| 成人激情免费在线| 国产精品77777| 久草在线看片| 国产成人av电影在线播放| 浓精h攵女乱爱av| 欧美日韩免费不卡视频一区二区三区 | 欧美性极品少妇| 国内欧美日韩| 99久久99久久| 国产区在线观看成人精品 | 亚洲伦理中文字幕| 视频在线不卡免费观看| 国产免费黄色小视频| 欧美亚洲禁片免费| 日韩美脚连裤袜丝袜在线| 樱花www成人免费视频| 婷婷六月综合亚洲| 91综合久久爱com| 一区二区精品免费视频| 日韩欧美国产一区二区| 亚州一区二区| 日本特级黄色大片| 色香色香欲天天天影视综合网| 亚洲视频国产| a级黄色片免费| 色狠狠av一区二区三区| 香蕉精品久久| 亚洲人成色77777| 亚洲日本欧美日韩高观看| 青草青在线视频| 国产精品十八以下禁看| 本田岬高潮一区二区三区| 男人资源在线播放| 91精品国产综合久久香蕉922| 国产农村妇女毛片精品久久麻豆| 校园春色亚洲| 日本一区二区三区视频在线播放 | 91在线国产电影| 国产精品美女久久久久av爽李琼 | 九色视频成人porny| 亚洲欧美日韩综合aⅴ视频| 成人综合网站| 亚洲一区二区三区乱码| 欧美视频中文一区二区三区在线观看| 日韩成人一级| 久久久精品麻豆| 中文字幕精品一区二区精品绿巨人 | 久久久久国产精品一区二区| 国产欧美一区二区在线播放| 亚洲视频一区二区免费在线观看 | 亚洲一区二区三区涩| 欧美日韩久久不卡| 欧美激情亚洲| 久久电影中文字幕| 91久色国产| 色综合久久中文综合久久97| 久久一区二区中文字幕| 粉嫩tv在线播放| 国产精品午夜国产小视频| 亚洲男女一区二区三区| 亚洲警察之高压线| 午夜视频国产| 国产精品九九九| 亚洲r级在线视频| 999久久久91| av在线首页| 久久综合九色综合久99| 欧美一区二区三区四区五区| 日韩国产精品久久| 北岛玲heyzo一区二区| 亚洲理论电影在线观看| xvideos亚洲| 国产亚洲精品久| 黄页视频在线免费观看| 日本精品va在线观看| 亚洲一区二区美女| 中文精品久久| 麻豆tv免费在线观看| 亚洲精品久久久久久一区二区| 亚洲国产99精品国自产| 国产91丝袜在线播放九色| 国色天香久久精品国产一区| 国产美女免费观看| 不卡一卡2卡3卡4卡精品在| 欧美一卡在线观看| 国产精品18久久久久久久久久久久| 欧美高清xxx| 91人人网站| 成人自拍网站| 亚洲男人天堂2019| 1024精品合集| 亚洲午夜精品久久久久久app| 影音先锋在线视频| 国产白丝袜美女久久久久| 日本亚洲精品在线观看| 欧美日韩成人在线| av在线综合网| 深爱激情综合网| 成年人黄视频在线观看| 日韩av高清在线看片| 国产成+人+综合+亚洲欧洲 | 欧美视频13p| 韩日av一区二区| 猛男gaygay欧美视频|