一、建立閉包
建立閉包的常見方式,就是在乙個函式內部建立另乙個函式。
二、作用域鏈
當某個函式被呼叫的時候,會建立乙個執行環境和相應的作用域鏈,然後使用arguments初始化物件。這個物件叫做活動物件。
在作用域鏈中,外部函式的活動物件始終處於第二位。以此類推,直到作用域鏈終點——全域性執行環境。 首先,讓我先來看看什麼叫做活動物件。
functioncompare(a,b)
else
if(aelse
}var result=compare(5,10);//
false
console.log(result);
這段**中,首先定義了compare()函式,然後在全域性作用域中呼叫了它。在呼叫這個函式的時候,建立了arguments、a、b這三個活動物件。他們處在作用域鏈的第一位。
而result、compare被稱為變數物件,他們處於全域性執行環境下,在作用域鏈中處於第二位。
全域性環境的變數物件始終存在,在函式中訪問乙個變數時,就會在作用域鏈中尋找具有相應名字的變數。函式執行完畢,活動物件就被銷毀。而閉包的特殊就在於此,活動物件沒有被銷毀!
看這段**:
functioncompare(propertyvalue)
else
if(a>b)
else
}}var fun=compare("value");
console.log(
typeof fun);//
function
var result=fun(5,10);
console.log(result);
//true
函式compare()中包含了乙個匿名函式,那麼,該匿名函式,也就是閉包的作用域鏈中,就會有compare()函式的活動物件。因此,該閉包作用域鏈其實有三節:
第一節,閉包的活動物件,obj1,obj2 和arguments;
第二節,compare()函式的活動物件,arguments和propertyvalue;
第三節,全域性變數物件,compare。
這意味著什麼意思呢?就是在compare()這個函式在執行完畢以後,他的活動物件propertyvalue和arguments也不會被銷毀。因為匿名函式的作用域鏈仍然在引用這個活動物件。也就是說,compare()執行完以後,其執行環境的作用域鏈會被銷毀,但是他的活動物件卻不會被銷毀
。除非匿名函式被銷毀。
而在js中,內建的工具函式settimeout,往往就會造就乙個閉包。
functionwait(message),1000);
}wait('5');//
5
timer()函式就是乙個閉包,即使wait()執行1000毫秒後,內部作用域仍然不會消失。timer具有wait()作用域的閉包。
三、閉包與變數
functionfun();
}return
result;
}var a=fun();
console.log(a);
//array(4) [, , , ]
好吧,這段**我還是看的半懂不懂。似乎理解他為什麼會返回這個,似乎又不理解。而且和書上寫的也不一樣啊。也沒返回4個「3」啊!這是為啥內?
for(var i=0;i<2;i++),i*1000);}console.log('daoda')//
daoda;2;2
看到沒有,竟然先輸出了"daoda",然後又輸出了兩個「2」!
首先解釋「2」是怎麼來的。首先,這個迴圈終止的條件是i不再小於2,也就是說,條件首次成立時,i的值為2。因此,輸出顯示的是迴圈結束時i的值。
延遲函式的**是在迴圈結束的時候才執行。即使執行的是settimeout(...,0),所有的**函式依然是在迴圈結束後才會執行。因此每次輸出的都是2!
你以為每次迭代都會有對應的i,但是根據作用域的原理,儘管迴圈中的5個函式是在各個迭代部分中分別定義的,但是它們卻都被封閉在乙個共享的全域性作用域中,因此實際上只有1個i。
for(var i=0;i<2;i++),i*1000);})();
}console.log('藍色橙汁');//
"藍色橙汁";2;2
iife會立即執行函式,為什麼輸出的還是兩個「2」呢?
這是因為iife的作用域是空的。他要有自己的變數,用來在每次迭代中儲存i的值才行。
**寫成這樣才可以:
for(var i=1;i<=5;i++),j*1000);})();
}
上面這段**可以做一些改進:
for(var i=1;i<=5;i++),j*1000);})(i);
}
奇怪的是,為什麼這裡我就理解了?
閉包的概念
因此 可以訪問外部函式的變數,其內部變數只能內部可訪問 閉包時塊級作用域,可以定義自己的變數,避免變數命名衝突,汙染外部變數 使用場景一 封裝私有變數,對外暴露get,set方法或其中一種 使用場景二 儲存外部函式的變數 使用場景三 使用場景三 當閉包被賦值給乙個生命較長的變數時,其所依賴的父函式的...
閉包的概念 轉
首先,我覺得,乙個概念,如果不理解也不影響使用的話,那麼,就沒必要去理解它 去學習它。閉包就是這樣乙個概念,你不理解它也能很好的用它。俺這兩年寫as3程式,是天天在和它打交道,甚至有過乙個function套乙個,乙個方法中套了20多個function的極端例子,但從未深究過它是怎麼實現的,它就像水和...
js 閉包概念,用法
1 我們常說的閉包就是函式巢狀函式,內部函式可以引用外部函式的引數和變數 如下 2 會涉及到js中的垃圾 機制 指 當函式執行完時,函式的變數將會收回,閉包就不一樣了 如下 3 閉包中當外部函式載入完時,外部函式的變數內部函式還可以繼續使用,不會 如下 4 閉包的好處 將乙個變數長期駐紮在記憶體中 ...