前言:
啊啊啊,看書真的很痛苦啊,還是好想做項目寫代碼才有意思,不過我現在缺的確是將知識體系化,所以不論看書多么痛苦都一定要堅持堅持啊,這才是我現在最需要的進步的地方,加油!
因為現在期末啦,下周一也就是明天開始就有考試,所以復習是主要的事情,看書的速度比較慢了,一周大概也就184頁(P110-P284), 雖然頁數比較少但是其中有ES中非常最重要的兩個概念——原型鏈和閉包,之前對於兩個知識的了解算是知其然不知其所以然的,所以在那兩章我也有意多花費了時間,確保我能夠吃透這個概念。以下算是我自己的一些理解,如果有不很正確的地方,希望大神們多多指教,康桑阿米達~
哦,對了,我看的JS書是《Javascript 高級程序設計(第3版)》,如果有正在看這本書的小伙伴可以一起哇~大家多多交流,互相學習嘛~
正文:
現在最流行的編程語言里面一定有“對象”的概念,我們的第一節實驗課老師就叫我們怎么找對象,所以可見對象對於程序猿的重要性,所以你有對象了嘛?:) 那這世界上對象千千萬,我們怎么知道哪個對象合適呢?總不能一個一個的相處試試看吧?好在我們發現很多對象都有相似之處,所以我們將他們相似的部分抽象出來,形成了一個全新的概念,在我們需要的時候,比對我們的需要和這個概念,再進行選擇,就會節省我們很多功夫並更好更快的獲得我們想要的結果。而這個概念在JS中就是引用類型,Object(JS中沒有類的概念,如果學過C++或者Java、C#等語言的,那也會很容易就對應get到JS中引用類型的)。Object確實是JS中非常強大的部分,但卻不是最有意思的,那最有意思的是什么?Function。
在JS中,Function也是一個Object的一個對象。而關於這個概念的延伸,像是繼承、原型鏈等等就又可以再開一把了,如果實在是飢渴難耐的,那就快去搜索大神們博客或者找一本《JavaScript高級程序設計》和我一起學習啦~所以,我們現在就將矛頭對准,閉包!開火,嘣嘣嘣嘣
在說閉包的概念之前,我們總得知道這個名詞到底是什么意思吧?
所以什么是閉包?函數。
既然就是函數為什么又特別要取個名字?它到底特別在哪?
能夠訪問另一個函數作用域中的變量。(此處的作用域姑且理解為{}之內)
For example,上個例子就知道了,不要問我例子是誰
function outerFunc(arg){ return function innerFunc(){ alert(arg); } }
此處名為outerFunc的函數返回了一個名為innerFunc函數,這個函數在內部只有一句“alert(arg);”,可是運用技能一眼看穿法,找不到arg,再往上,哇哦,在outerFunc的參數那找到了呢,真開心。所以這個innerFunc(函數)訪問了outerFunc(另一個函數)作用域內(在outerFunc的{}中,但沒在innerFunc的{}中)的變量(arg),所以這個innerFunc就是一個閉包。(大多數時候,不會為閉包命名,此處只為更好的說明。)
OK,閉包的概念知道啦,那如何形成閉包這個現象的呢?顯然剛剛別有深意,欲拒還迎的作用域使的小把戲啦,別怕,我們立馬拿下。
“當某個函數被調用時,會創建一個執行環境及相應的作用域鏈。”
“每個執行環境都有一個表示變量的對象——變量對象。(variable object)。”
當然還是要先名詞解釋,要是都不知道這個名詞指的什么,那還怎么玩。
作用域:也就是變量對象的別稱。
作用域鏈:就是作用域和鏈唄。一條把作用域像臘肉穿起來的鏈子。它只是一條鏈子所以作用域鏈就只保存着變量對象的地址,而不是變量對象本身。
執行環境:執行環境指向自己獨有的作用域鏈,作用域鏈又按照當前函數作用域,外部函數作用域,外部函數的外部函數作用域....直至全局作用域。
1 function outerFunc(arg){ 2 3 return function innerFunc(){ 4 alert(arg); 5 } 6 7 } 8 9 var result = outerFunc(1); //返回innerFunc函數 10 result(); //輸出1
還是剛才的函數,還是原來的配方,再加點料,看看效果。