天天看點

關于javascript閉包--整理篇

閉包:是指文法域位于某個特定的區域,具有持續參照(讀寫)位于該區域内自身範圍之外的執行域上的非持久型變量值能力的段落。這些外部執行域的非持久型變量神奇地保留它們在閉包最初定義(或建立)時的值(深連結)。簡單來說,閉包就是在另一個作用域中儲存了一份它從上一級函數或作用域取得的變量(鍵值對),而這些鍵值對是不會随上一級函數的執行完成而銷毀。周愛民說得更清楚,閉包就是“屬性表”,閉包就是一個資料塊,閉包就是一個存放着“Name=Value”的對照表。就這麼簡單。但是,必須強調,閉包是一個運作期概念。

閉包的特點:   1:作為一個函數變量的一個引用,當函數傳回時,其處于激活狀态。   2:一個閉包就是當一個函數傳回時,一個沒有釋放資源的棧區。 簡單的說,javascript允許使用内部函數---即函數定義和函數表達式位于另一個函數的函數體内。而且,這些内部函數可以通路它們所在的外部函數中聲明的所有局部變量、參數和聲明的其他内部函數。當其中一個這樣的内部函數在包含它們的外部函數之外被調用時,就會形成閉包。

解決辦法:

現在比較讓人認同的閉包實作有如下三種:

1:

with

(obj){

//這裡是對象閉包

}

2:

(

function

(){

//函數閉包

})()

3:

try

{

//...

}

catch

(e) {

//catch閉包 但IE裡不行

}

例子如下:三個<li>節點彈出相應的參數

<ul>

<li id=

"a1"

>aa</li>

<li id=

"a2"

>aa</li>

<li id=

"a3"

>aa</li>

</ul>

<script type=

"text/javascript"

>

for

(

var

i=1; i < 4; i++){

var

id = document.getElementById(

"a"

+ i);

id.onclick =

function

(){

alert(i);

//現在都是傳回4

}

}

</script>

例子解決方案:

1:使用函數閉包。

var

lists = document.getElementsByTagName(

"li"

);

for

(

var

i=0,l=lists.length; i < l; i++){

lists[i].onclick = (

function

(i){

//儲存于外部函函數

return

function

(){

alert(i);

}

})(i);

}

var

lists = document.getElementsByTagName(

"li"

);

for

(

var

i=0,l=lists.length; i < l; i++){

lists[i].onclick =

new

function

(){

var

t = i;

return

function

(){

alert(t+1)

}

}

}

2:利用事件代理

var

ul = document.getElementsByTagName(

"ul"

)[0];

ul.onclick =

function

(){

var

e = arguments[0] || window.event,

target = e.srcElement ? e.srcElement : e.target;

if

(target.nodeName.toLowerCase() ==

"li"

){

alert(target.id.slice(-1))

}

}

3:将暫時變量保留于元素節點上。

var

lists = document.getElementsByTagName(

"li"

);

for

(

var

i=0,t=0,el; el = list[i++];){

el.i = t++

el.onclick =

function

(){

alert(

this

.i)

}

}

4:使用with語句造成的對象閉包。

var

els = document.getElementsByTagName(

"li"

)

for

(

var

i=0,n=els.length;i<n;i++){

with

({i:i})

els[i].onclick =

function

() { alert(

this

.innerHTML+i) };

}

5:使用try...catch語句構造的異常閉包:

var

lists = document.getElementsByTagName(

"li"

);

for

(

var

i=0,l=lists.length; i < l; i++){

try

{

throw

i;

}

catch

(i){

lists[i].onclick = 

function

(){

alert(i)

}

}

}

繼續閱讀