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

關(guān)于JavaScript閉包的應(yīng)用

開發(fā) 前端
閉包就是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)。MDN 上面這么說:閉包是一種特殊的對象。它由兩部分構(gòu)成:函數(shù),以及創(chuàng)建該函數(shù)的環(huán)境。環(huán)境由閉包創(chuàng)建時在作用域中的任何局部變量組成。創(chuàng)建閉包最常見方式,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)。

[[171507]]

什么是閉包(Closure)

簡單講,閉包就是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)。

MDN 上面這么說:閉包是一種特殊的對象。它由兩部分構(gòu)成:函數(shù),以及創(chuàng)建該函數(shù)的環(huán)境。環(huán)境由閉包創(chuàng)建時在作用域中的任何局部變量組成。

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

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

產(chǎn)生一個閉包

創(chuàng)建閉包最常見方式,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)。下面例子中的 closure 就是一個閉包:

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

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

閉包的注意事項

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

  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 都是閉包。它們共享相同的函數(shù)定義,但是保存了不同的環(huán)境。在 add5 的環(huán)境中,x 為 5。而在 add10 中,x 則為 10。***通過 null 釋放了 add5 和 add10 對閉包的引用。

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

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

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

  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(); // 連續(xù)打印 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()()實際上是在全局作用域中調(diào)用了匿名函數(shù),this指向了window。這里要理解函數(shù)名與函數(shù)功能(或者稱函數(shù)值)是分割開的,不要認(rèn)為函數(shù)在哪里,其內(nèi)部的this就指向哪里。匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其 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  

閉包的應(yīng)用

應(yīng)用閉包的主要場合是:設(shè)計私有的方法和變量。

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

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

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

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

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

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

上面是普通模式創(chuàng)建的單例,下面使用模塊模式創(chuàng)建單例:

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

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

  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. })();  

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

一個閉包計數(shù)器 

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

閉包的缺陷

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

***再來一些有關(guān)閉包的面試題

下面代碼中,標(biāo)記 ? 的地方輸出分別是什么?

  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.  

參考資料

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2021-02-21 16:21:19

JavaScript閉包前端

2023-09-06 16:55:33

JavaScript閉包

2020-02-12 16:58:15

JavaScript前端技術(shù)

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應(yīng)用方法

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閉包函數(shù)

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

2017-05-22 16:08:30

前端開發(fā)javascript閉包

2021-01-13 11:25:12

JavaScript閉包函數(shù)

2009-03-17 15:36:29

JavaScript循環(huán)事件

2021-12-06 07:15:48

Javascript作用域閉包

2011-08-24 17:09:35

LUA閉包函數(shù)
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久草精品视频 | 宅女噜噜66国产精品观看免费 | 欧美日韩中文国产一区发布 | 中文字幕一区二区视频 | 婷婷桃色网 | www.黄色在线观看 | 天天干.com| 精品亚洲一区二区 | 久久爱黑人激情av摘花 | 久久一| 欧美淫 | 2018国产大陆天天弄 | 亚洲444eee在线观看 | 亚洲成人免费观看 | 日韩视频在线播放 | 中文字幕国产视频 | 亚洲精彩视频 | 在线观看亚洲精品 | 久久男女视频 | 中文字幕99 | 亚洲国产精品99久久久久久久久 | 国产一区二区精品自拍 | 可以免费观看的av | 久久久精 | 国产精品视频入口 | 在线欧美亚洲 | 91国在线高清视频 | 国产三级网站 | 亚洲一区 中文字幕 | 91国在线高清视频 | 亚洲欧美在线免费观看 | 欧美情趣视频 | 亚洲精品久久 | 久久久这里都是精品 | 国产亚洲一区二区精品 | 亚洲在线中文字幕 | 国产精品99久久久久久动医院 | 欧美性区| 天天躁日日躁狠狠的躁天龙影院 | 久热国产精品视频 | 一区二区三区在线看 |