要想完全明白JavaScript的閉包,要先明白js中的一些基礎(chǔ)原理,然后我再給出一些例子來(lái)講解閉包。

  在執(zhí)行JavaScript時(shí)會(huì)創(chuàng)建一個(gè)執(zhí)行環(huán)境(excution context),執(zhí)行環(huán)境定義了變量或函數(shù)可以訪問(wèn)的其他數(shù)據(jù)。每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象(variable object 有些地方叫域?qū)ο?Scope object)),在執(zhí)行環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中。雖然我們編寫的代碼無(wú)法訪問(wèn)這個(gè)對(duì)象,但解析器在處理數(shù)據(jù)時(shí)會(huì)在后臺(tái)使用它。

  全局執(zhí)行環(huán)境是最外層的一個(gè)執(zhí)行環(huán)境。根據(jù)js實(shí)現(xiàn)的宿主環(huán)境的不同,環(huán)境對(duì)象不一樣。瀏覽器中,全局執(zhí)行環(huán)境是window,node.js的全局變量是global,所有的全局變量和方法都保存在全局對(duì)象中。

  每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。當(dāng)調(diào)用進(jìn)入一個(gè)函數(shù)時(shí),函數(shù)的執(zhí)行環(huán)境就會(huì)被創(chuàng)建。代碼在執(zhí)行環(huán)境中運(yùn)行時(shí),他創(chuàng)建用于保存變量對(duì)象的作用域鏈(scope chain)。他的作用是保存一個(gè)執(zhí)行環(huán)境所有可以訪問(wèn)的變量或函數(shù)的有序集合。作用域的最前面是當(dāng)前執(zhí)行的代碼所在執(zhí)行環(huán)境的變量對(duì)象。如果當(dāng)前的執(zhí)行環(huán)境是一個(gè)函數(shù),就將函數(shù)的活動(dòng)對(duì)象作為變量對(duì)象,剛開(kāi)始時(shí)只有一個(gè)變量arguments。作用域鏈中的下一個(gè)變量對(duì)象是包含當(dāng)前環(huán)境變量的外部環(huán)境也就是他的調(diào)用者,再下一個(gè)是更外層的,至到全局執(zhí)行環(huán)境。

  所以在一個(gè)執(zhí)行中的方法內(nèi)訪問(wèn)一個(gè)不存在于這個(gè)執(zhí)行環(huán)境中的變量時(shí)不會(huì)報(bào)錯(cuò),解析器會(huì)從作用域鏈的頂端的變量對(duì)象開(kāi)始找,如果找不到就找下一個(gè)執(zhí)行環(huán)境的變量對(duì)象,一直到全局環(huán)境變量。如果有則停止查找。如果找到全局變量對(duì)象還是沒(méi)有發(fā)現(xiàn),就會(huì)報(bào)錯(cuò)。

  簡(jiǎn)單說(shuō)就是,一個(gè)函數(shù)體內(nèi)就是一個(gè)執(zhí)行環(huán)境,當(dāng)一個(gè)函數(shù)在執(zhí)行時(shí),會(huì)創(chuàng)建一個(gè)作用鏈,這個(gè)鏈中有自己的變量對(duì)象,同時(shí)也有外層的變量對(duì)象。

  示例1:全局執(zhí)行環(huán)境

        		

延伸閱讀

學(xué)習(xí)是年輕人改變自己的最好方式-Java培訓(xùn),做最負(fù)責(zé)任的教育,學(xué)習(xí)改變命運(yùn),軟件學(xué)習(xí),再就業(yè),大學(xué)生如何就業(yè),幫大學(xué)生找到好工作,lphotoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開(kāi)發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)學(xué)習(xí)是年輕人改變自己的最好方式