日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
關(guān)于JavaScript閉包的應(yīng)用

什么是閉包(Closure)

站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到德陽(yáng)網(wǎng)站設(shè)計(jì)與德陽(yáng)網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請(qǐng)域名、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋德陽(yáng)地區(qū)。

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

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

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

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

產(chǎn)生一個(gè)閉包

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

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

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

閉包的注意事項(xiàng)

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

 
 
  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. console.log(add5(2));  // 7
  9. console.log(add10(2)); // 12
  10. // 釋放對(duì)閉包的引用
  11. add5 = null;
  12. add10 = null; 

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

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

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

閉包只能取得包含函數(shù)中任何變量的***一個(gè)值,這是因?yàn)殚]包所保存的是整個(gè)變量對(duì)象,而不是某個(gè)特殊的變量。

 
 
  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. }
  12. test(); // 連續(xù)打印 10 個(gè) 10 

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

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

對(duì)于上面兩種代碼的解釋,請(qǐng)看我在 segmentfault 上面的提問(wèn):鏈接

閉包中的 this 對(duì)象

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

obj.getName()()實(shí)際上是在全局作用域中調(diào)用了匿名函數(shù),this指向了window。這里要理解函數(shù)名與函數(shù)功能(或者稱函數(shù)值)是分割開(kāi)的,不要認(rèn)為函數(shù)在哪里,其內(nèi)部的this就指向哪里。匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其 this 對(duì)象通常指向 window。

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

閉包的應(yīng)用

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

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

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

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

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

單例(singleton):指的是只有一個(gè)實(shí)例的對(duì)象。JavaScript 一般以對(duì)象字面量的方式來(lái)創(chuàng)建一個(gè)單例對(duì)象。

 
 
  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.     objEvent.addEvent = addEvent;
  10.     objEvent.removeEvent = removeEvent;
  11. })(); 

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

一個(gè)閉包計(jì)數(shù)器

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

閉包的缺陷

  • 閉包的缺點(diǎn)就是常駐內(nèi)存會(huì)增大內(nèi)存使用量,并且使用不當(dāng)很容易造成內(nèi)存泄露。
  • 如果不是因?yàn)槟承┨厥馊蝿?wù)而需要閉包,在沒(méi)有必要的情況下,在其它函數(shù)中創(chuàng)建函數(shù)是不明智的,因?yàn)殚]包對(duì)腳本性能具有負(fù)面影響,包括處理速度和內(nèi)存消耗。

***再來(lá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. var b = fun(0).fun(1).fun(2).fun(3);  // ?
  14. var c = fun(0).fun(1);  // ?
  15. c.fun(2);        // ?
  16. c.fun(3);        // ? 
 
 
  1. undefined
  2. 0
  3. 0
  4. 0
  5. undefined, 0, 1, 2
  6. undefined, 0
  7. 1

參考資料

  • 【書(shū)】《JavaScript 高級(jí)程序設(shè)計(jì)(第三版)》
  • 【文章】學(xué)習(xí)Javascript閉包(Closure)
  • 【文章】【JavaScript】【函數(shù)】閉包閉包!

當(dāng)前文章:關(guān)于JavaScript閉包的應(yīng)用
網(wǎng)站網(wǎng)址:http://www.5511xx.com/article/cosejco.html