亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        淺析javascript語言中的函數(shù)閉包現(xiàn)象

        2012-12-31 00:00:00徐紅梅

        摘要:閉包在很多javascript高級應(yīng)用中都會出現(xiàn)。本文主要以javascript語言為例分析閉包現(xiàn)象的形成,理解閉包的運(yùn)行機(jī)制及使用。

        關(guān)鍵詞:閉包;內(nèi)部變量;作用域

        中圖分類號:TP312.2 文獻(xiàn)標(biāo)識碼:A 文章編號:1007-9599 (2012) 23-0000-02

        閉包問題是英格蘭Brighton ALT.NET Beers活動中提出來的。閉包的概念很抽象,如果不用代碼來說明,將很難用描述性語句把它解釋清楚。所以本文將以javascript語言為例解釋說明什么是閉包,分析閉包的運(yùn)行機(jī)制及使用注意事項(xiàng)。

        1 閉包的概念

        什么是閉包?在計(jì)算機(jī)科學(xué)中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數(shù)。這個(gè)被引用的自由變量將和這個(gè)函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。ECMAScript允許使用內(nèi)部函數(shù)--即函數(shù)定義和函數(shù)表達(dá)式位于另一個(gè)函數(shù)的函數(shù)體內(nèi)。[1]而且,這些內(nèi)部函數(shù)可以訪問它們所在的外部函數(shù)中聲明的所有局部變量、參數(shù)和聲明的其他內(nèi)部函數(shù)。當(dāng)其中一個(gè)這樣的內(nèi)部函數(shù)在包含它們的外部函數(shù)之外被調(diào)用時(shí),就會形成閉包。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。由于在Javascript語言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解成“定義在一個(gè)函數(shù)內(nèi)部的函數(shù)”。

        2 理解閉包在javascript中的運(yùn)行及使用

        2.1 如何理解閉包

        閉包的創(chuàng)建相對容易,有時(shí)創(chuàng)建閉包編程人員根本沒有意識到這是閉包,尤其是在IE等常見的瀏覽器環(huán)境下運(yùn)行下,所編寫的程序在很大程度上存在潛在的問題。因此在編寫JAVASCRIPT高級應(yīng)用程序是,對閉包的使用和它的運(yùn)行機(jī)制必須有一定了解。而了解閉包運(yùn)行機(jī)制的就要先解析在編寫過程中的環(huán)境變量及作用域。

        javascript中每個(gè)函數(shù)都是一個(gè)函數(shù)對象(函數(shù)實(shí)例),既然是對象,就有相關(guān)的屬性和方法。[scope]就是每個(gè)函數(shù)對象都具有的一個(gè)僅供javascript引擎內(nèi)部使用的屬性,該屬性是一個(gè)集合(類似于鏈表結(jié)構(gòu)),集合中保存了該函數(shù)在被創(chuàng)建時(shí)的作用域中的所有對象,而這個(gè)作用域集合形成的鏈表則被稱為ScopeChain(作用域鏈)[2]。該作用域鏈中保存的作用域?qū)ο?,就是該函?shù)可以訪問的所有數(shù)據(jù)。例如定義一個(gè)函數(shù)求兩個(gè)數(shù)的和運(yùn)算

        當(dāng)add函數(shù)被創(chuàng)建時(shí),函數(shù)所在的全局作用域的全局對象被放置到add函數(shù)的作用域鏈([[scope]]屬性)中。從圖2-1中看到作用域鏈的第一個(gè)對象保存的是全局對象,全局對象中保存了諸如this,window,document以及全局對象中的add函數(shù)。這也就是為什么可以在在全局作用域下的函數(shù)中訪問window(this),訪問全局變量,訪問函數(shù)自身的原因。當(dāng)局部變量和全局變量同名時(shí),會使用局部變量而不使用全局變量,

        2.2 全局變量在javascript函數(shù)中的應(yīng)用

        分析Javascript特殊的變量作用域是可以方便編程人員理解閉包。在編程語言中,所有的變量的作用域從函數(shù)的角度來說都可以分成:全局變量和局部變量。而Javascript語言的是比較特殊的一種語言,它可以從函數(shù)內(nèi)部可以直接讀取并引用全局變量。一個(gè)閉包就是一個(gè)引用了其被生成的環(huán)境中、所屬的變量范圍內(nèi)的所有變量的函數(shù)。[3]例如定義了一個(gè)函數(shù)f1,代碼如下:

        var x = 1;

        function f1()

        {var y = 1;

        var result = x + y;

        document.wirte(“result=”, result);

        };

        這里我們首先定義了一個(gè)變量“x”,值為1。然后我們定義無參無返回值函數(shù)f1,在f1函數(shù)內(nèi)部result中使用了“x”變量。這個(gè)變量是被f1 引用了,自動被添加到了f1的運(yùn)行環(huán)境中了。

        當(dāng)我們執(zhí)行f1時(shí),它會輸出了一個(gè)預(yù)期的結(jié)果2。但函數(shù)f1執(zhí)行時(shí),原始的“x”此時(shí)已經(jīng)不在是它當(dāng)初的變量環(huán)境,但它仍然能被使用。

        2.3 局部變量在javascript函數(shù)中的應(yīng)用

        在Javascript語言中,函數(shù)內(nèi)部的子函數(shù)可以直接讀取局部變量,所以閉包也可以說成是“嵌套定義在一個(gè)函數(shù)內(nèi)部的函數(shù)”。而閉包就成為了函數(shù)內(nèi)部和函數(shù)外部相聯(lián)系一個(gè)媒介。

        因此,有時(shí)候當(dāng)需要得到函數(shù)內(nèi)的局部變量??梢栽诤瘮?shù)的內(nèi)部,再定義一個(gè)函數(shù)。例如定義了一個(gè)函數(shù)f2代碼如下:

        function f2()

        {n=1;

        function f3()

        {var s=n+2

        alert(“s=”+ s);//s的結(jié)果=3 }

        return f3;

        }

        在代碼中,函數(shù)f3就被定義在函數(shù)f2內(nèi)部,這時(shí)函數(shù)f2內(nèi)部的所有局部變量,對函數(shù)f3都是有效的。即n可以被f3函數(shù)引用,但是f3內(nèi)部的局部變量,對f2就是不可見的。即s變量在f2函數(shù)中不可見。這就是Javascript語言中的“chain scope”,計(jì)算機(jī)專業(yè)術(shù)語稱為“鏈?zhǔn)阶饔糜颉?,在鏈?zhǔn)阶饔糜蛑凶訉ο髸饘酉蛏蠈ふ宜懈笇ο蟮淖兞?。所以,父對象的所有變量,對子對象都是有效的,子對象可以隨意使用父對象的變量,但是子對象中的變量卻屏蔽了,父對象沒法使用它的變量。

        在代碼運(yùn)行中,函數(shù)f3可以使用f2中的局部變量n,但父對象函數(shù)f2想要讀取f3的內(nèi)部變量怎么辦?這里只要把f3作為返回值,則函數(shù)f2即可讀取到內(nèi)部變量s的值。這里的f3()就是一個(gè)閉包。

        2.4 閉包在javascript語言中的應(yīng)用

        閉包可以用在許多地方。它的最大用處有兩個(gè),一個(gè)是前面提到的可以讀取函數(shù)內(nèi)部的變量,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中。例如定義一個(gè)函數(shù)a,在函數(shù)a內(nèi)部定義如下函數(shù)b,代碼如下:

        function a() //外層函數(shù)a

        { var n=1; //臨時(shí)變量n

        function b()//內(nèi)層函數(shù)b

        {

        alert(n++);//引用外層臨時(shí)變量n

        }

        return b; }//返回函數(shù)b

        var result=a (); //調(diào)用函數(shù)a,函數(shù)b被引用

        result(); //函數(shù)b中n變量被引用值為2.

        }

        在這段代碼中,函數(shù)b實(shí)際上就是一個(gè)閉包函數(shù)。在程序代碼中函數(shù)b被調(diào)用了兩次,變量n值第一次的n=1,第二次的n=2。這說明了,函數(shù)a中的局部變量n一直駐留在內(nèi)存中,當(dāng)函數(shù)a調(diào)用后沒有被釋放,第二次調(diào)用時(shí)仍然再使用。這種情況說明,函數(shù)b可以引用函數(shù)a的全局變量,在運(yùn)行中函數(shù)b始終在內(nèi)存中,而函數(shù)b的存在依賴于函數(shù)a,在調(diào)用結(jié)束后,函數(shù)a也會駐留在內(nèi)存,不會被javascript的垃圾回收機(jī)制回收。

        從上面的例子我們得出以下在javascript中使用閉包是的結(jié)論:

        (1)使用閉包可以使函數(shù)內(nèi)的變量更加安全,防止其他變量通過任何其他路徑訪問該變量。例如上例,變量n只有函數(shù)b才能訪問,而其他函數(shù)想要訪問函數(shù)a中的n變量時(shí)不可能的。

        (2)使用閉包可以使變量在內(nèi)存中駐留。方便函數(shù)的調(diào)用和使用該變量。依然如上例,由于該代碼創(chuàng)建了一個(gè)閉包,當(dāng)每次執(zhí)行result()時(shí),n都會被累加。

        (3)使用閉包可以封裝JS私有屬性和私有方法,使函數(shù)內(nèi)部的變量不會被外部訪問。

        3 閉包應(yīng)用中的注意事項(xiàng)

        (1)合理利用和創(chuàng)建閉包。閉包會使函數(shù)中的變量長久保存內(nèi)存中,消耗內(nèi)存的資源,造成網(wǎng)頁崩潰等性能問題,從而導(dǎo)致IE中內(nèi)存泄露等。所以在編寫該代碼運(yùn)行后,要將不使用的局部變量刪除。

        (2)閉包很輕易的可以改變父函數(shù)內(nèi)部變量值,所以謹(jǐn)慎使用閉包。在把閉包當(dāng)作父函數(shù)的公有方法或把內(nèi)部變量當(dāng)作父函數(shù)的私有屬性時(shí),父函數(shù)內(nèi)的變量值不能隨意改變,造成函數(shù)變量值的混亂。

        (3)警惕和及時(shí)察覺意外閉包現(xiàn)象。前面的例子也說明了閉包很容易創(chuàng)建,在javascript中允許使用閉包,所以在沒有認(rèn)識到閉包是一種語言特性的JavaScript時(shí),編程人員會按照想法來使用內(nèi)部函數(shù)。但對使用內(nèi)部函數(shù)的結(jié)果并不明了,有可能在定義函數(shù)時(shí)已經(jīng)定義了一個(gè)閉包而沒有意識到。會使最終結(jié)果并不是編程人員向要的結(jié)果。在IE的內(nèi)存泄漏問題中,閉包意外創(chuàng)建的會存在很多潛在的技術(shù)問題,從而影響到代碼的性能及結(jié)果。

        4 結(jié)束語

        閉包問題不在javascript語言于是否允許使用閉包。而在于在理解了閉包的運(yùn)行機(jī)制基礎(chǔ)上,謹(jǐn)慎有效的使用閉包,才能寫出更為安全的代碼,為編寫程序提供方便。

        參考文獻(xiàn):

        [1]David Flanagan.JavaScript權(quán)威指南(第5版)[M].李強(qiáng).北京:機(jī)械工業(yè)出版社,2007.

        [2]Nicholas C.Zakas.JavaScript高級程序設(shè)計(jì)(第3版)[M].李松峰,曹力.北京:人民郵電出版社,2012.

        [3]張?jiān)品?JavaScript閉包技術(shù)及IE內(nèi)存泄漏分析[J].電腦知識與技術(shù),2008,35.

        [4]鄧緒高.Javascript中變量作用域淺析[J].信息與電腦(理論版),2010.12/

        [作者簡介]徐紅梅(1977.10-),碩士學(xué)位,四川職業(yè)技術(shù)學(xué)院計(jì)算機(jī)系講師。

        国产在视频线精品视频二代| 青春草在线视频免费观看| 国产超碰人人模人人爽人人喊| 无码人妻精品丰满熟妇区| 亚洲熟妇20| 日本一区二区在线资源| 亚洲乱码中文字幕一线区| 性刺激的大陆三级视频| 少妇被爽到高潮动态图| 九一成人AV无码一区二区三区| 中文字幕亚洲精品第一页| 日本在线一区二区三区视频观看| 熟女体下毛荫荫黑森林| 日韩人妻无码一区二区三区| 无码片久久久天堂中文字幕| 内射中出后入内射极品女神视频| 在线观看国产视频午夜| 在线精品无码字幕无码av| 人与嘼av免费| 亚洲国产色图在线视频| 东京热日本av在线观看| 亚洲一卡2卡3卡4卡5卡精品| 国产成人一区二区三中文| 午夜在线观看一区二区三区四区| 一区二区三区日韩精品视频| 免费无码av一区二区| 天天爱天天做天天爽| 午夜日本精品一区二区| 自拍偷拍 视频一区二区| 久久99精品久久久久久秒播| 欧美日韩亚洲国产千人斩| 国产免费99久久精品| 国产精品高清网站| 亚洲成色www久久网站夜月| 亚洲香蕉毛片久久网站老妇人| 伊人狼人激情综合影院| 国产精品情侣呻吟对白视频| 亚洲av纯肉无码精品动漫| 欧美精品一本久久男人的天堂| 日本在线免费不卡一区二区三区| av影院在线免费观看不卡|