Javascript的閉包
簡介
Closure
所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個函數(shù)),因而這些變量也是該表達(dá)式的一部分。
閉包是 ECMAScript (JavaScript)最強(qiáng)大的特性之一,但用好閉包的前提是必須理解閉包。閉包的創(chuàng)建相對容易,人們甚至?xí)诓唤?jīng)意間創(chuàng)建閉包,但這些無意創(chuàng)建的閉包卻存在潛在的危害,尤其是在比較常見的瀏覽器環(huán)境下。如果想要揚(yáng)長避短地使用閉包這一特性,則必須了解它們的工作機(jī)制。而閉包工作機(jī)制的實現(xiàn)很大程度上有賴于標(biāo)識符(或者說對象屬性)解析過程中作用域的角色。
關(guān)于閉包,最簡單的描述就是 ECMAScript 允許使用內(nèi)部函數(shù)--即函數(shù)定義和函數(shù)表達(dá)式位于另一個函數(shù)的函數(shù)體內(nèi)。而且,這些內(nèi)部函數(shù)可以訪問它們所在的外部函數(shù)中聲明的所有局部變量、參數(shù)和聲明的其他內(nèi)部函數(shù)。當(dāng)其中一個這樣的內(nèi)部函數(shù)在包含它們的外部函數(shù)之外被調(diào)用時,就會形成閉包。也就是說,內(nèi)部函數(shù)會在外部函數(shù)返回后被執(zhí)行。而當(dāng)這個內(nèi)部函數(shù)執(zhí)行時,它仍然必需訪問其外部函數(shù)的局部變量、參數(shù)以及其他內(nèi)部函數(shù)。這些局部變量、參數(shù)和函數(shù)聲明(最初時)的值是外部函數(shù)返回時的值,但也會受到內(nèi)部函數(shù)的影響。
遺憾的是,要適當(dāng)?shù)乩斫忾]包就必須理解閉包背后運(yùn)行的機(jī)制,以及許多相關(guān)的技術(shù)細(xì)節(jié)。雖然本文的前半部分并沒有涉及 ECMA 262 規(guī)范指定的某些算法,但仍然有許多無法回避或簡化的內(nèi)容。對于個別熟悉對象屬性名解析的人來說,可以跳過相關(guān)的內(nèi)容,但是除非你對閉包也非常熟悉,否則最好是不要跳過下面幾節(jié)。
對象屬性名解析
ECMAScript 認(rèn)可兩類對象:原生(Native)對象和宿主(Host)對象,其中宿主對象包含一個被稱為內(nèi)置對象的原生對象的子類(ECMA 262 3rd Ed Section 4.3)。原生對象屬于語言,而宿主對象由環(huán)境提供,比如說可能是文檔對象、DOM 等類似的對象。
原生對象具有松散和動態(tài)的命名屬性(對于某些實現(xiàn)的內(nèi)置對象子類別而言,動態(tài)性是受限的--但這不是太大的問題)。對象的命名屬性用于保存值,該值可以是指向另一個對象(Objects)的引用(在這個意義上說,函數(shù)也是對象),也可以是一些基本的數(shù)據(jù)類型,比如:String、Number、Boolean、Null 或 Undefined。其中比較特殊的是 Undefined 類型,因為可以給對象的屬性指定一個 Undefined 類型的值,而不會刪除對象的相應(yīng)屬性。而且,該屬性只是保存著 undefined 值。
下面簡要介紹一下如何設(shè)置和讀取對象的屬性值,并最大程度地體現(xiàn)相應(yīng)的內(nèi)部細(xì)節(jié)。
值的賦予
對象的命名屬性可以通過為該命名屬性賦值來創(chuàng)建,或重新賦值。即,對于:
var objectRef = new Object(); //創(chuàng)建一個普通的 javascript 對象。
可以通過下面語句來創(chuàng)建名為 “testNumber” 的屬性:
objectRef.testNumber = 5;
/* - 或- */
objectRef["testNumber"] = 5;
在賦值之前,對象中沒有“testNumber” 屬性,但在賦值后,則創(chuàng)建一個屬性。之后的任何賦值語句都不需要再創(chuàng)建這個屬性,而只會重新設(shè)置它的值:
objectRef.testNumber = 8;
/* - 或- */
objectRef["testNumber"] = 8;
稍后我們會介紹,Javascript 對象都有原型(prototypes)屬性,而這些原型本身也是對象,因而也可以帶有命名的屬性。但是,原型對象命名屬性的作用并不體現(xiàn)在賦值階段。同樣,在將值賦給其命名屬性時,如果對象沒有該屬性則會創(chuàng)建該命名屬性,否則會重設(shè)該屬性的值。
更詳細(xì)的請查看下面的文章:
http://demo.jb51.net/js/javascript_bibao/index.htm
- Javascript閉包演示代碼小結(jié)
- javascript 閉包疑問
- 深入理解Javascript閉包 新手版
- 淺析javascript閉包 實例分析
- javascript學(xué)習(xí)之閉包分析
- JavaScript中通過閉包解決只能取得包含函數(shù)中任何變量最后一個值的問題
- javascript閉包的理解和實例
- javascript深入理解js閉包
- javascript,jquery閉包概念分析
- JavaScript中的閉包原理分析
- JavaScript 閉包在封裝函數(shù)時的簡單分析
- javascript 常見的閉包問題的解決辦法
- javascript 閉包函數(shù)做顯隱內(nèi)容
- javascript 閉包
相關(guān)文章
JavaScript代碼壓縮工具UglifyJS和Google Closure Compiler的基本用法
網(wǎng)上搜索了,目前主流的Js代碼壓縮工具主要有Uglify、YUI Compressor、Google Closure Compiler,簡單試用了UglifyJS 和Google Closure Compiler 兩種工具的基本用法,需要的朋友可以參考下2020-04-04js復(fù)制網(wǎng)頁內(nèi)容并兼容各主流瀏覽器的代碼
js 復(fù)制網(wǎng)頁內(nèi)容的方法代碼有很多不過要兼容各瀏覽器就不多了,下面有個不錯的方法,大家可以嘗試操作下2013-12-12JS實現(xiàn)數(shù)字格式千分位相互轉(zhuǎn)換方法
下面小編就為大家?guī)硪黄狫S實現(xiàn)數(shù)字格式千分位相互轉(zhuǎn)換方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08LayUi使用switch開關(guān),動態(tài)的去控制它是否被啟用的方法
今天小編就為大家分享一篇LayUi使用switch開關(guān),動態(tài)的去控制它是否被啟用的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09用JavaScript實現(xiàn)簡單網(wǎng)頁時鐘
這篇文章主要為大家詳細(xì)介紹了用JavaScript實現(xiàn)簡單網(wǎng)頁時鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08