還是閉包,閉包在javascript的編程中作用太大。仍然還是要加深理解
這次的例子是來自《javascript設計模式》
pro javascript design patterns sourcecode 這本書算是比較老的了。上帝要我學好javascript,花了不少力氣。本地圖書館的 javascript的設計模式的書籍盡然悉數(shù)盡收了。名字直接帶js 設計模式的書四本都有,《精通javascript》,《javascript面向?qū)ο缶幊獭酚袃?nèi)容涉及。幾本javascript的動物書都有。
直接看代碼,這個代碼的問題,其實在tab編程的時候,已經(jīng)在用了,但是還不是太清楚。關(guān)鍵點:每次調(diào)用閉包的時候,都會創(chuàng)建一個單獨的作用域,或者叫作用域氣泡,這個作用域中的變量和其他閉包的變量是隔絕的,所以叫氣泡。javascript通過閉包可以達到隱藏和封裝信息的用途。
//foo()函數(shù)是外部函數(shù)。bar()是內(nèi)部函數(shù),var a=10是使用var 關(guān)鍵字
//定義的變量,而且位于foo()函數(shù)內(nèi)部,在全局作用域下是訪問不到的
//所以是私有變量。bar()函數(shù)位于foo()函數(shù)內(nèi)部,擁有訪問foo()作用域的權(quán)利。
function foo() {
var a = 10;
function bar() {//bar()函數(shù)是內(nèi)部函數(shù),可以訪問到var a 變量,或者叫捕獲
a *= 2;
return a; //return 局部變量
}
return bar; //返回內(nèi)部函數(shù),這樣在foo()作用域外也可以訪問到bar
//函數(shù),由于變量a也從bar()函數(shù)返回,變量從 foo()作用域中脫逃出來。
}
var baz = foo(); // baz是函數(shù)foo()的引用
baz(); // returns 20. //奇妙的地方在這里
baz(); // returns 40.//也是
baz(); // returns 80.//也是
//持續(xù)調(diào)用baz實際上在同一個foo()作用域里面的操作.這里就只有一個
//作用域存在,變量a也就可以一直保存改變的值了。
//下面就不同了,blat重新引用了foo()函數(shù),重新創(chuàng)建了一個閉包作用
//域,變量a是從10開始的,可以理解為初始化。
var blat = foo(); //這是foo()的另一引用。這里有點繞了。
//閉包的變量是在定義閉包時候就定義好的,與運行時是無關(guān)的。
//所以在第二次引用閉包是變量的初始值還是10
//這個地方是不是有些熟悉?是的,和函數(shù)綁定的對象剛好是相反的,
//函數(shù)綁定的作用域?qū)ο笫窃谶\行時綁定的,與定義函數(shù)時的作用域無關(guān)
blat(); // returns 20
blat(); // returns 40