既然說閉包的化,我們就先來說說函數(shù),
js 閉包之一
。慢慢的進入進入正題(1)函數(shù)申明
f1();
function f1(){
alert("1")
}//結(jié)果 1
(2)函數(shù)定義
f1();
var f1=function(){
alert(''1")
}// 直接報錯了
其實原因是這樣的函數(shù)申明:會在代碼執(zhí)行之前提前加載到作用域中這樣在執(zhí)行發(fā)f1()的時候就可以找到了。但是函數(shù)的定義是:先在內(nèi)存里賣弄創(chuàng)建了一塊區(qū)域,之后通過一個f1() 指針指向這塊區(qū)域,開始的時候這塊區(qū)域是沒有名字的.
函數(shù)的作用域鏈
var number="a";
var showNumber=function(){
alert(this.number);
}
function changeNumber(){
var anothernumber="b";
function savenumber(){
var tempnumber=anothernumber;
anothernumber=number;
number=tempnumber
}
savenumber();
}
changeNumber();
showNumber() //結(jié)果是“b”
其實我的理解就是,在進行js 函數(shù)調(diào)用的時候,會為每一個函數(shù)自動的添加一個scope屬性通過這個屬性來指向一塊內(nèi)存,然后這個內(nèi)存就會包含這個這個函數(shù)的上下文相關(guān)的變量,如果這個函數(shù)里面又包含了一個新的函數(shù),那么又會自動的分配一塊內(nèi)存,當然這個函數(shù)又會自動的繼承了他的上級所執(zhí)行的變量(這個繼承可能說的不太對感覺是這個意思?)
其實可以這么理解哈。我們在帶調(diào)用changnumber()的時候首先changenumber()這個函數(shù)的作用域鏈包括自己的(anothernumber 這個變量,然后就是savenumber()。最后就是上文的作用域,也就是number()和shownumber()這個全局的。這個時候savenumber 也會被執(zhí)行那么他就會去繼承他的上一級的作用域,和上上級的作用域,)那么這個時候savenumer去改變number 的值,這個時候number 的值就是b,最后當我們調(diào)用shownumber()的時候自然出現(xiàn)的值就是結(jié)果“b”了,
電腦資料
《js 閉包之一》(http://www.msguai.com)。我看一個例子看看閉包產(chǎn)生的原因:
function compareObjectFunction(prop){
//匿名函數(shù)
return function(obj1>obj2{
if(obj1[prop]>obj2[prop]) return 1;
else if(obj1[prop else return 0; }) } var o1={name:"Leon",age:23}; var o2={name:"Ade",age:28}; /* 在中這個時候變量并沒有被釋放,于是這個時候作用域就變大了 */ var compare=compareObjectFunction("age"); var rel=compare(o1,o2); alert(rel1) 復制代碼 我們看看他的作用域鏈 于是我們來解釋一下到底是如何實現(xiàn)的。首先我們執(zhí)行compareobjectfunction()的時候會產(chǎn)什么如下的作用域鏈Global和compareobject()這個。當compareobjecfunction執(zhí)行完過后我們就會釋放相應的作用域但是這個時候com這個匿名函數(shù)指向了相同的作用域,Global和compareobject()這個時候并不會發(fā)生釋放這個作用域的動作,于是compar、這個就獲取到相應的參數(shù)了。于是乎作用域就發(fā)生了擴大。這個就是閉包產(chǎn)生的原理。其實我的理解就是里面的函數(shù)調(diào)用了外部函數(shù)的變量(或者說擴大了函數(shù)的訪問變量的范圍) 下面我們再來看一個例子: function fn1(){ var fns=new Array(); for(var i=0;i<10;i++){ fns[i]=function(){ return 1; } } return fns; } var fs=fn1(); for(var i=0;i { alert(fs[i]()) }