亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript閉包與作用域鏈實例分析

2019-11-19 12:14:35
字體:
來源:轉載
供稿:網友

本文實例講述了JavaScript閉包與作用域鏈。分享給大家供大家參考,具體如下:

閉包定義

閉包指的是有權訪問另一個函數作用域中的變量的函數。創建閉包的常見方式,就是在一個函數A內部創建另一個函數B,那么函數B就是一個閉包,可以訪問函數A作用域中的所有變量。

JavaScript的閉包與作用域鏈密不可分,因此本文可以和JavaScript的作用域鏈相對照分析,一定可以對JavaScript的閉包和作用域鏈有更深的理解。

下面我們仍然以createComparisonFunction為例進行閉包的分析。

//step1: define createComparisonFunctionfunction createComparisonFunction(propertyName){  return function(object1, object2){    var value1 = object1[propertyName];    var value2 = object2[propertyName];    if (value1 < value2) {      return -1;    } else if (value1 > value2) {      return 1;    } else {      return 0;    }  };}//step2: call createComparisonFunctionvar compareName = createComparisonFunction("name");var compareAge = createComparisonFunction("age");//step3: call comparevar object1 = {  name : "Nicholas",  age : 25};var object2 = {  name : "Greg",  age : 27};var result1 = compareName(object1, object2); // 1var result2 = compareAge(object1, object2); // -1//step4: dereference closure for recycle memorycompareName = null;compareAge = null;

在這個例子中,匿名函數function(object1, object2)是一個閉包,能訪問createComparisonFunction作用域里的所有變量,自然也包含propertyName屬性, 因為propertyName參數的不同,導致比較的屬性也有所不同,從而函數執行結果也有不同。

閉包與變量

JavaScript的作用域鏈中,我們了解到JavaScript是通過作用域鏈來確定函數執行環境的作用域的,這種機制會引出一個值得注意的副作用,即閉包只能取得包含函數中任何變量的最后一個值。閉包是通過引用外部函數的活動對象來訪問該活動對象中的所有變量,因此在外部函數執行過程中,這些變量的值可能會變化,但是在外部函數執行完畢之后,外部函數的活動對象便不會再改變,因此在執行閉包的時候,閉包通過作用域鏈訪問到外部函數的活動對象中的所有變量都只可能是在外部函數執行完畢之后,外部函數的活動對象中最后所保存的值。我們通過一個例子來說明這種副作用。

function createFunctions(){  var result = new Array();  for (var i = 0; i < 10; i++){    result[i] = function(){      return i;    };  }  return result;}var functions = createFunctions();for(var i = 0; i < functions.length; i++){  console.log(functions[i]());}

輸出的結果是

10 10 10 10 10 10 10 10 10 10

從表面上看,似乎每個函數都應該返回自己的索引值,但實際上,每個函數都返回10。因為每個函數的作用域鏈中都保存著createFunctions函數的活動對象,所以他們引用的都是這個createFunctions函數的活動對象中的變量i,在createFunctions函數返回之后,變量i的值是10,此時每個函數都引用著保存變量i的同一個變量對象,所以每個函數內部i的值都是10。

我們以調用functions[3]()為例,圖解一下:

Closure函數的Function對象的作用域鏈引用的createFunctions的活動對象中保留的變量i的值為10。所以不管是functions[3]()還是functions[5](),其運行時上下文的作用域鏈引用的createFunctions的活動對象都是同一個活動對象,該活動對象中保留的變量i的值是10。

如何避免這種局面?我們可以通過創建另一個匿名函數讓閉包的行為符合預期。

function createFunctions(){  var result = new Array();  for (var i = 0; i < 10; i++){    result[i] = function(num){      return function(){        return num;      }    }(i);  }  return result;}var functions = createFunctions();for(var i = 0; i < functions.length; i++){  console.log(functions[i]());}

輸出的結果是

0 1 2 3 4 5 6 7 8 9

這個代碼片段與前面的代碼的區別在于立即調用了一個匿名函數function(num),使得閉包function()引用的是function(num)的活動對象,訪問的是該活動對象中的變量num而不是createFunctions活動對象中的變量i,而在立即調用function(num)的num是索引值0,1,2…9。

我們仍舊以調用functions[3]()為例,圖解一下:

在執行createFunctions函數的時候,會依次調用function(0), function(1) … function(9), 生成function(0), function(1) … function(9)這10個function(num)的活動對象,而result[0], result[1] … result[9]這10個匿名函數對象的作用域鏈分別引用這10個function(num)的活動對象,而其中的變量num的值也對應的為0, 1 … 9。

所以不管是functions[3]()還是functions[5](),其運行時上下文的作用域鏈都會引用在執行createFunctions函數時候所執行的function(3)或者function(5)這些function(num)函數的活動對象,這些活動對象都是不同的活動對象,其中保留的num值分別為3, 5。

更多關于JavaScript相關內容感興趣的讀者可查看本站專題:《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數學運算用法總結

希望本文所述對大家JavaScript程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲一区中文字幕在线观看| 欧美性猛交xxxx富婆弯腰| 庆余年2免费日韩剧观看大牛| 久久久免费精品视频| 成人中文字幕+乱码+中文字幕| 亚洲aⅴ日韩av电影在线观看| 在线电影欧美日韩一区二区私密| 亚洲乱码国产乱码精品精天堂| 精品久久久久久久久中文字幕| 欧美激情精品久久久久| 91高清在线免费观看| 欧美大片免费观看在线观看网站推荐| 亚洲深夜福利网站| 日韩69视频在线观看| 欧美高清激情视频| 色妞欧美日韩在线| 亚洲一区二区中文字幕| 国产精品爱啪在线线免费观看| 成人a级免费视频| 亚洲影视九九影院在线观看| 日韩av电影在线播放| 麻豆国产精品va在线观看不卡| 亚洲欧美日韩综合| 精品视频—区二区三区免费| 免费不卡欧美自拍视频| 日本国产精品视频| 欧美区在线播放| 午夜精品视频在线| 日韩中文字幕在线看| 色偷偷噜噜噜亚洲男人的天堂| 粉嫩老牛aⅴ一区二区三区| 国产成人精品视频| 成人av资源在线播放| 欧美交受高潮1| 久久久久久亚洲| 国产精品高清网站| 日本欧美黄网站| 国产欧美一区二区| 日韩欧美成人精品| 91情侣偷在线精品国产| 91精品免费视频| 成人精品一区二区三区电影免费| 亚洲视频欧洲视频| 亚洲精品国产精品久久清纯直播| 国产精品国语对白| 2019中文字幕在线观看| 日韩高清中文字幕| 精品日韩视频在线观看| 国产精品白丝jk喷水视频一区| 精品久久久久久久久久久久久| 国内精品久久久久| 一区二区三区国产在线观看| 欧美视频专区一二在线观看| 日韩精品在线看| 国产婷婷97碰碰久久人人蜜臀| 亚洲国产美女精品久久久久∴| 欧美精品手机在线| 亚洲天堂av女优| 91精品国产免费久久久久久| 国产日韩欧美夫妻视频在线观看| 国产精品∨欧美精品v日韩精品| 亚洲毛片在线观看| 九九精品在线观看| 精品亚洲一区二区三区四区五区| 黑人精品xxx一区| 亚洲欧美日韩天堂一区二区| 亚洲人成在线电影| 国产精品美女免费| 久久综合伊人77777尤物| 97超碰国产精品女人人人爽| 欧美精品aaa| 欧美裸体xxxx| 日韩精品在线私人| 91精品国产综合久久久久久久久| 日韩电影免费观看在线观看| 一区二区三区动漫| 国产丝袜一区二区三区免费视频| 91精品国产色综合| 茄子视频成人在线| 欧美日韩在线视频一区| 亚洲第一区第二区| 欧美激情乱人伦一区| 精品国产区一区二区三区在线观看| 欧美大学生性色视频| 欧美激情亚洲精品| 亚洲自拍偷拍区| 欧美激情视频三区| 国产精品一二三在线| 日韩成人av网址| 亚洲香蕉av在线一区二区三区| 久热精品在线视频| 韩剧1988在线观看免费完整版| 久久久久久久激情视频| 欧美日韩裸体免费视频| 欧美在线视频在线播放完整版免费观看| 色综合久久88色综合天天看泰| 第一福利永久视频精品| 欧美一级高清免费| 成人情趣片在线观看免费| 国产精品成人av性教育| 亚洲第一二三四五区| 午夜精品久久久久久99热软件| 91豆花精品一区| 国产精品日韩久久久久| 亚洲aa在线观看| 国产精品日韩在线播放| 国产丝袜高跟一区| 成人性生交大片免费观看嘿嘿视频| 久久精品青青大伊人av| 中文字幕免费精品一区高清| 成人精品一区二区三区| www亚洲欧美| 色视频www在线播放国产成人| 亚洲深夜福利在线| 日韩专区在线播放| 欧美视频裸体精品| 在线看日韩av| 国产精品亚发布| 91在线高清免费观看| 尤物99国产成人精品视频| 中文字幕日韩欧美精品在线观看| 国产精品久久久久久久久免费看| 欧美一区第一页| 成人xxxx视频| 精品中文字幕在线| 日韩成人av网| 欧美激情亚洲自拍| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产亚洲精品成人av久久ww| 成人黄色短视频在线观看| 自拍亚洲一区欧美另类| 91精品国产自产在线老师啪| 日韩av在线电影网| 久99久在线视频| 91精品国产自产在线老师啪| 亚洲成色777777在线观看影院| 久久理论片午夜琪琪电影网| 成人乱人伦精品视频在线观看| 日本一区二区三区在线播放| 久热精品视频在线| 最近中文字幕2019免费| 成人免费高清完整版在线观看| 国产97在线播放| 国产日韩欧美成人| 欧美电影在线免费观看网站| 中文字幕视频在线免费欧美日韩综合在线看| 亚洲网站视频福利| 日韩欧美在线一区| 欧美成人在线免费视频| 亚洲成人在线网| 欧美超级免费视 在线| 精品久久久久久久大神国产| 国产精品久久97| 欧洲成人在线视频| 精品久久久久久久久久ntr影视| 91爱视频在线| 亚洲国内精品在线| 一区二区三区动漫| www.久久久久| 91午夜理伦私人影院| 欧美成年人视频网站欧美| 国产不卡视频在线| wwwwwwww亚洲| 国产精品96久久久久久又黄又硬|