淺談JS執行環境及範圍

來源:互聯網
上載者:User

標籤:

   今天剛剛開通部落格,也是第一次寫博文,略感緊張。作為一個表達能力弱弱的人來說,自己花三分鐘理解一個知識點,當別人問起時,也許需要30分鐘才只是讓別人知道自己在說什麼,一點也不誇張,希望在部落格上可以練習對語言的組織能力並記錄學習筆記與大家一起交流。

    進入正題>>

首先,相關的概念定義如下:

  1. 執行環境: 所有 JavaScript 代碼都是在一個執行環境中被執行的。執行環境是一個概念,一種機制,用來完成JavaScript運行時在範圍、生存期等方面的處理,它定義了變數或函數有權訪問的其他資料(包含了外部資料),決定他們各自的行為。包括以下分類:

     全域執行環境: 全域環境是最外圍的一個執行環境,根據ECMAScript實現所在的宿主環境不同,表示執行環境的對象也不一樣,在web中,全域執行環境被認為是window對象。

     函數執行環境: 每個函數都有自己的執行環境。

  2. 變數對象: 每個執行環境都有一個變數對象與之關聯,執行環境中定義的所有變數及函數(只包含在當前函數內定義的函數,局部變數)都儲存在這個對象中,我們編寫的代碼無法直接存取這個對象,但解析器在處理資料時會在後台使用它。

  3. 範圍: 變數或方法有存取權限的代碼空間,即變數或函數起作用的地區。

  4. 範圍鏈: 由當前環境棧中對應的變數對象組成。範圍的用途,是保證對執行環境有權訪問的所有變數和函數的有序訪問,範圍前端,始終是當前執行的代碼所在的環境對應的變數對象,下一變數對象來自包含(外部)環境,而再下一變數對象則來自下一包含環境,一直延續到全域執行環境。

以下分析將協助大家理解上面的概念:

1. 執行環境與變數對象之間的對應關係

   每個執行環境會有一個變數對象與之關聯,該變數對象儲存了執行環境中定義的所有局部變數及函數,變數對象具有動態性,只有在定義變數的語句得到執行才會將該變數添加到變數對象中,如下例中

function showA () {    consoloe.log(a);  // 變數對象中沒有儲存a    alert(a);}

2. 程式執行時,環境棧與執行環境的關係

   當執行流進入一個函數時,即該函數正在執行,函數的執行環境就會被推入一個環境棧中,所有處在執行流的執行環境將有次序地儲存在環境棧中,在函數執行之後,棧將其執行環境彈出,把控制權交給原來的執行環境。所以在程式執行中,環境棧是不斷變化的,伴隨著執行環境的出入,如下所示:

(摘自:笨蛋的座右銘的博文)

3. 理解環境棧,執行環境與範圍鏈之間的關係

  在某一時刻,環境棧中儲存的執行環境是一定的,以下面的程式為例,當fn2正在執行時

function Fn1() {   var a = 1;   function Fn2() {        var b = 2;    }   Fn2(); // 當程式執行到此時}Fn1();

  此時環境棧狀態如下:

     此時環境棧包括:全域執行環境,fn1執行環境,fn2執行環境, 根據執行環境和變數對象具有的一一對應的關係,所以當前環境棧中執行環境和變數對象有以下對應關係

                              (摘自:笨蛋的座右銘的博文)

  根據範圍鏈的定義,由右邊的變數對象所組成的就是當前範圍鏈,鏈的前端為Fn2執行環境對應的變數對象

4. 範圍鏈的作用(標識符解析機制)

  範圍鏈的用途,是保證對執行環境有權訪問的所有變數和函數的有序訪問(包括外部資料)

  標識符解析是沿著範圍鏈一級一級地搜尋標識符的過程,搜尋始終從範圍鏈的前端開始,然後逐級地向後回溯,直到找到標識符為止。

樣本1:

var color = ‘blue‘;functionshowColor () { alert(color);}showColor(); // blue

  在例1中,標識符解析從範圍鏈前端開始,順著範圍鏈往後找,開始在showColor()的執行環境對應的變數對象中未能找到,之外在包含環境(全域執行環境)的變數對象中找到color變數,停止搜尋,所以此時的color變數引用了全域中定義的color變數,於是輸出為blue;

例2:

var color = ‘blue‘;function showColor () {   var  color = ‘red‘; alert(color);}showColor(); // red

  在例2中,標識符解析從範圍鏈前端開始,順著範圍鏈往後找,在showColor()函數對應的執行環境對應的變數對象找到變數color,標識符解析程式立即停止搜尋,此時color變數為函數中定義的color,於是輸出為red

  由以上兩個例子中可以看出範圍鏈保證對執行環境有權訪問的所有變數和函數的有序訪問的原理:範圍鏈有序地儲存了變數對象,由前向後,局部變數和函數往往儲存在較前的變數對象中,因此被標識符解析的機會大於全域變數,也就有了局部變數會覆蓋全域變數的現象,這樣就保證了變數的有序訪問。  

5. 範圍與變數對象,執行環境的關係

  由定義可知,範圍即函數或變數的作用地區。

  變數或函數具有範圍的原因,就是在環境中定義的變數僅儲存在了該執行環境對應的物件變數中,執行環境在環境棧中彈出之後,範圍鏈中找不到該對變數對象,以下面為例

function showColor () {   var  color = ‘red‘;}showColor(); // redalert(color); // color is undefined

  為什麼在全域環境下showColor()內定義的變數不可訪問呢,這是因為當函數執行到該語句時,color變數儲存在了showColor()環境對應的變數對象中,現在showColor()已經執行完畢,該執行環境也從環境棧中彈出並銷毀,所以此時的範圍鏈也不包括showColor()的執行環境對應的變數對象了,因為標識符解析是順著範圍鏈尋找變數的,所以這個過程不再能搜尋到color變數,所以color變得只有定義該變數的函數中才能訪問,具有一定範圍的範圍。

以上內容為本人的理解,錯誤之處歡迎大家積極打臉~~

    

 

淺談JS執行環境及範圍

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.