



全文預(yù)覽已結(jié)束
下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
閉包(Closures)在ECMAScript中,函數(shù)是“第一類”對(duì)象。這個(gè)名詞意味著函數(shù)可以作為參數(shù)被傳遞給其他函數(shù)使用 (在這種情況下,函數(shù)被稱為“funargs”“functional arguments”的縮寫(xiě)譯注:這里不知翻譯為泛函參數(shù)是否恰當(dāng))。接收“funargs”的函數(shù)被稱之為 高階函數(shù)(higher-order functions) ,或者更接近數(shù)學(xué)概念的話,被稱為 運(yùn)算符(operators) 。其他函數(shù)的運(yùn)行時(shí)也會(huì)返回函數(shù),這些返回的函數(shù)被稱為 function valued 函數(shù) (有 functional value 的函數(shù))。“funargs”與“functional values”有兩個(gè)概念上的問(wèn)題,這兩個(gè)子問(wèn)題被稱為“Funarg problem” (“泛函參數(shù)問(wèn)題”)。要準(zhǔn)確解決泛函參數(shù)問(wèn)題,需要引入 閉包(closures) 到的概念。讓我們仔細(xì)描述這兩個(gè)問(wèn)題(我們可以見(jiàn)到,在ECMAScript中使用了函數(shù)的Scope屬性來(lái)解決這個(gè)問(wèn)題)。“funarg problem”的一個(gè)子問(wèn)題是“upward funarg problem”譯注:或許可以翻譯為:向上查找的函數(shù)參數(shù)問(wèn)題。當(dāng)一個(gè)函數(shù)從其他函數(shù)返回到外部的時(shí)候,這個(gè)問(wèn)題將會(huì)出現(xiàn)。要能夠在外部上下文結(jié)束時(shí),進(jìn)入外部上下文的變量,內(nèi)部函數(shù) 在創(chuàng)建的時(shí)候(at creation moment) 需要將之存儲(chǔ)進(jìn)Scope屬性的父元素的作用域中。然后當(dāng)函數(shù)被激活時(shí),上下文的作用域鏈表現(xiàn)為激活對(duì)象與Scope屬性的組合(事實(shí)上,可以在上圖見(jiàn)到):Scope chain = Activation object + Scope作用域鏈 = 活動(dòng)對(duì)象 + Scope請(qǐng)注意,最主要的事情是函數(shù)在被創(chuàng)建時(shí)保存外部作用域,是因?yàn)檫@個(gè) 被保存的作用域鏈(saved scope chain) 將會(huì)在未來(lái)的函數(shù)調(diào)用中用于變量查找。function foo() var x = 10; return function bar() console.log(x); ; / foo返回的也是一個(gè)function/ 并且這個(gè)返回的function可以隨意使用內(nèi)部的變量x var returnedFunction = foo(); / 全局變量 xvar x = 20; / 支持返回的functionreturnedFunction(); / 結(jié)果是10而不是20這種形式的作用域稱為靜態(tài)作用域static/lexical scope。上面的x變量就是在函數(shù)bar的Scope中搜尋到的。理論上來(lái)說(shuō),也會(huì)有動(dòng)態(tài)作用域dynamic scope, 也就是上述的x被解釋為20,而不是10. 但是EMCAScript不使用動(dòng)態(tài)作用域?!癴unarg problem”的另一個(gè)類型就是自上而下”downward funarg problem”.在這種情況下,父級(jí)的上下會(huì)存在,但是在判斷一個(gè)變量值的時(shí)候會(huì)有多義性。也就是,這個(gè)變量究竟應(yīng)該使用哪個(gè)作用域。是在函數(shù)創(chuàng)建時(shí)的作用域呢,還是在執(zhí)行時(shí)的作用域呢?為了避免這種多義性,可以采用閉包,也就是使用靜態(tài)作用域。請(qǐng)看下面的例子:/ 全局變量 xvar x = 10; / 全局functionfunction foo() console.log(x); (function (funArg) / 局部變量 x var x = 20; / 這不會(huì)有歧義 / 因?yàn)槲覀兪褂胒oo函數(shù)的Scope里保存的全局變量x, / 并不是caller作用域的x funArg(); / 10, 而不是20 )(foo); / 將foo作為一個(gè)funarg傳遞下去從上述的情況,我們似乎可以斷定,在語(yǔ)言中,使用靜態(tài)作用域是閉包的一個(gè)強(qiáng)制性要求。不過(guò),在某些語(yǔ)言中,會(huì)提供動(dòng)態(tài)和靜態(tài)作用域的結(jié)合,可以允許開(kāi)發(fā)員選擇哪一種作用域。但是在ECMAScript中,只采用了靜態(tài)作用域。所以ECMAScript完全支持使用Scope的屬性。我們可以給閉包得出如下定義:A closure is a combination of a code block (in ECMAScript this is a function) and statically/lexically saved all parent scopes.Thus, via these saved scopes a function may easily refer free variables.閉包是一系列代碼塊(在ECMAScript中是函數(shù)),并且靜態(tài)保存所有父級(jí)的作用域。通過(guò)這些保存的作用域來(lái)搜尋到函數(shù)中的自由變量。請(qǐng)注意,因?yàn)槊恳粋€(gè)普通函數(shù)在創(chuàng)建時(shí)保存了Scope,理論上,ECMAScript中所有函數(shù)都是閉包。還有一個(gè)很重要的點(diǎn),幾個(gè)函數(shù)可能含有相同的父級(jí)作用域(這是一個(gè)很普遍的情況,例如有好幾個(gè)內(nèi)部或者全局的函數(shù))。在這種情況下,在Scope中存在的變量是會(huì)共享的。一個(gè)閉包中變量的變化,也會(huì)影響另一個(gè)閉包的。function baz() var x = 1; return foo: function foo() return +x; , bar: function bar() return -x; ; var closures = baz(); console.log( closures.foo(), / 2 closures.bar() / 1);上述代碼可以用這張圖來(lái)表示:共享的Scope在某個(gè)循環(huán)中創(chuàng)建多個(gè)函數(shù)時(shí),上圖會(huì)引發(fā)一個(gè)困惑。如果在創(chuàng)建的函數(shù)中使用循環(huán)變量(如”k”),那么所有的函數(shù)都使用同樣的循環(huán)變量,導(dǎo)致一些程序員經(jīng)常會(huì)得不到預(yù)期值?,F(xiàn)在清楚為什么會(huì)產(chǎn)生如此問(wèn)題了因?yàn)樗泻瘮?shù)共享同一個(gè)Scope,其中循環(huán)變量為最后一次復(fù)賦值。var data = ; for (var k = 0; k 3; k+) datak = function () alert(k); ; data0(); / 3, but not 0data1(); / 3, but not 1data2(); / 3, but not 2有一些用以解決這類問(wèn)題的技術(shù)。其中一種技巧是在作用域鏈中提供一個(gè)額外的對(duì)象,比如增加一個(gè)函數(shù):var data = ; fo
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 學(xué)校污染物管理制度
- 學(xué)校綜合部管理制度
- 學(xué)校防疫情管理制度
- 學(xué)生教寢室管理制度
- 學(xué)雷鋒組織管理制度
- 安全標(biāo)注派管理制度
- 安徽公積金管理制度
- 安裝材料庫(kù)管理制度
- 定制廠配件管理制度
- 實(shí)木家具廠管理制度
- 手術(shù)室綠色通道病人搶救
- 《保密制度培訓(xùn)》課件
- 【MOOC】醫(yī)學(xué)物理學(xué)-山東大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 糖尿病周血管病變
- 《保健食品知識(shí)》課件
- 標(biāo)準(zhǔn)隔音施工方案
- 2024年專利代理人專利法律知識(shí)考試試卷及參考答案
- 《工傷預(yù)防教育》 課件 第二章 常見(jiàn)事故工傷預(yù)防
- 風(fēng)險(xiǎn)分級(jí)管控與隱患排查治理管理制度
- ISO27001-2013信息安全管理體系要求
- 山東省臨沂市2024年中考生物試卷
評(píng)論
0/150
提交評(píng)論