成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

關于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閉包

2009-07-24 17:30:37

Javascript閉

2020-02-12 16:58:15

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閉包

2010-06-23 10:24:42

Javascript閉

2016-09-18 20:53:16

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作用域

2017-05-22 16:08:30

前端開發javascript閉包

2021-01-13 11:25:12

JavaScript閉包函數

2009-03-17 15:36:29

JavaScript循環事件

2021-12-06 07:15:48

Javascript作用域閉包

2010-06-29 08:39:25

Python閉包

2011-08-24 17:09:35

LUA閉包函數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人午夜精品 | 正在播放国产精品 | 精品免费看| 99热在线播放 | 国产精品久久久久久一区二区三区 | 午夜免费网站 | 日韩一区二区三区视频在线观看 | 欧美日韩淫片 | 欧美精品导航 | 亚洲国产精品99久久久久久久久 | 国产91一区二区三区 | 国精日本亚洲欧州国产中文久久 | 精品国产91 | 日韩免费视频一区二区 | 在线视频一区二区 | 日韩精品一区二区三区 | 免费观看一级毛片 | 国产91观看 | 日本在线小视频 | 99热最新网址 | 日韩一区二区在线视频 | 99久久婷婷国产亚洲终合精品 | 亚洲一区二区在线 | 午夜精品一区二区三区在线视频 | 精精国产视频 | 91免费观看视频 | 亚洲欧美精品在线观看 | 久久综合亚洲 | 亚洲综合久久久 | 欧美人妖网站 | 精品国产欧美一区二区三区成人 | 国产一区二区三区久久久久久久久 | 欧美一级欧美一级在线播放 | 国产日韩欧美精品一区二区 | 色噜噜狠狠色综合中国 | 久久久久91 | 欧美国产精品一区二区三区 | 美女在线观看av | 欧美性猛交一区二区三区精品 | 一级一片在线观看 | 成人h视频 |