談JS中的做用域鏈與原型鏈(1)

      學習前端也有一段時間了,以爲本身能夠與你們分享一些我當初遇到疑惑的東西,但願能給對此問題有疑惑的朋友帶來一點幫助。javascript

      先來普及一下JS的概念(不要嫌我囉嗦,可能一些朋友開始學習JS是跟着視頻和寫好的代碼學的,應該有一部分對它的結構或者說它的歷史還不太瞭解),JavaScript由三種東西組成,一個叫ECMAScript,一個叫DOM,還有一個叫BOM,咱們如今說的JS實際上是它的核心——ECMAScript,簡稱ES。現在市面上的瀏覽器大部分是運行的ES5,但有一些也支持ES6,某些技術大牛都是用ES6編程而後轉ES5,工具是Babel。但咱們如今首要學習的仍是ES5,只有深刻理解了ES5才能作好其餘事情。html

  言歸正傳,今天咱們談的是ES5裏面的做用域鏈和原型鏈,當時我學習這一章的時候也是比較懼怕的,由於之前學習生物的時候啊,什麼DNA鏈啊生物鏈啊,就感受特複雜,對鏈這個玩意有種「一朝被蛇咬十年怕井繩」的感受。後來在不斷地學習與編碼過程當中呢,我逐步的理解了這一些東西,也感謝一些前輩們的文獻與代碼。前端

  說到底做用域鏈,顧名思義,它是與做用域在一塊兒的,何爲做用域,咱們知道JS裏的function,它是用來聲明一個函數的,每個函數運行的時候會擁有一個本身的執行環境,每一個執行環境都能擁有一個位置來存儲這個環境裏面定義的變量和函數,當這個執行環境的全部代碼執行完了以後,該環境被銷燬,保存在其中的全部變量和函數定義也被銷燬掉了,咱們能夠把這一個執行環境稱爲一個做用域。(這裏值得一提的是ES5沒有塊級做用域的概念,只有函數裏面的東西運行完會被銷燬,不在函數裏的東西,好比for(var i=0;i<10,i++)這個i不在函數裏,而是在一個全局的循環中,它就是一個全局變量。這些問題一些大公司正在協商解決,ES6裏大致上已經優化的很好了)java

  說完了做用域,咱們就能夠來說講做用域鏈了,做用域鏈是單向的。全局window是最大的做用域,全局裏聲明的函數是次一級的做用域,這樣的函數裏面能夠訪問到全局裏的各類變量和函數,但在全局中訪問不到這個函數裏面的函數和變量;這樣次一級裏面的函數是再次一級,它一樣也是能夠訪問上一級和全局的函數與變量,而上級訪問不到這個裏面的東西,這樣一層一層的遞進,就成了一條鏈子,也就是做用域鏈;編程

  咱們看一串代碼:瀏覽器

 1 <!DOCTYPE html>
 2 <html>
 3 
 4     <head>
 5         <meta charset="UTF-8">
 6         <title></title>
 7     </head>
 8 
 9     <body>
10         <script type="text/javascript">
11             var idol = "J.J";
12 
13             function writeIdol() {
14                 console.log("個人偶像是" + idol); //J.J(能夠訪問11行全局的idol)
15                 idol = "eason"; //修改了11行idol的值
16                 function askAnotherIdol() {
17                     var anotherIdol = "echo";
18                     console.log("個人偶像是" + idol); //15行「eason」
19                     console.log("其餘的偶像有" + anotherIdol) //17行「echo」
20                 }
21                 askAnotherIdol();
22                 console.log("個人偶像是" + idol); //這個時候獲得的是15行「eason」
23                 console.log("其餘的偶像有" + anotherIdol) //得不到了,由於做用域鏈是單向的
24             }
25             writeIdol();
26             //執行順序爲:writeIdol函數執行==>輸出idol(「J.J」)==>修改idol爲"eason"==>執行askAnotherIdol函數
27             //==>在函數內部聲明新變量anotherIdol值爲"echo",輸出全局idol(已修改「eason」)==>輸出其餘的偶像有「echo」
28             //==>輸出全局idol(已修改「eason」)==>輸出anotherIdol(anotherIdol is not defined,由於做用域鏈的單向)
29         </script>
30     </body>
31 
32 </html>

  做用域鏈能夠經過這個例子來理解,通俗點,大魚吃小魚,小魚吃蝦米——大魚能夠吃小魚,小魚卻吃不了大魚。咱們能夠把全局當成蝦米,最裏面的函數當大魚就好啦,雖然理解起來有點奇怪,若是沒有本身的理解方式,這樣套用一下也是能夠的嘛。函數

  做者也是第一次寫博客,若是寫的不太好或者有疑惑的,歡迎你們提出建議和問題,由於要吃飯啦,本篇就先寫個我對做用域鏈的理解吧,原型鏈在下一篇好好寫寫。工具

相關文章
相關標籤/搜索