JavaScript之執行環境及範圍

來源:互聯網
上載者:User

標籤:全域   作用   不用   語言   order   表達   編譯   ima   div   

     執行環境定義了變數或函數有權訪問的其他資料,決定了它們各自的行為。每個執行環境都有一個與之關聯的 變數對象,環境中定義的所有變數和函數都儲存在這個對象中。我們編寫的代碼是無法訪問這個對象的,但解析器在處理資料時會在後台使用它。     全域執行環境是最外圍的一個執行環境,在Web瀏覽器中,全域執行環境被認為是window對象,因此所有全域變數和函數都是作為window對象的屬性和方法來建立的。某個執行環境中的所有代碼執行完畢後,該環境就會被銷毀,儲存在其中的所有變數和函數定義也隨之銷毀。     每個函數都有自己的執行環境,當執行流進入一個函數時,函數的環境就會被推入一個環境棧中,在函數執行後,棧將其環境彈出,將控制權返回給之前的執行環境。ECMAScript程式中的執行流正是由這個方便的機制控制著。     當代碼在一個環境中執行時,會建立變數對象的一個 範圍鏈。範圍鏈的用途,是保證對執行環境有權訪問的所有變數和函數進行的有序訪問。範圍鏈的前端,始終都是當前執行的代碼所在環境的變數對象,如果這個環境是函數,則將其 使用中的物件作為變數對象。活動變數最開始時只包含一個變數,即 arguments對象(這個對象在全域環境中是不存在的)。範圍鏈中的下一個變數對象來自包含(外部)環境,再下一個變數對象則來自於再下下個包含(外部)環境,這樣一直延續到全域執行環境,全域執行環境的變數對象始終都是範圍鏈中的最後一個對象。      標識符解析是沿著範圍鏈一級一級向上(外)搜尋 標識符的過程。搜尋過程始終從範圍鏈的前端開始,然後逐級向後回溯,直至找到標識符為止。(比如:在全域執行環境中定義了一個name屬性,當在一個函數中使用了未聲明的變數name,這時,js在先行編譯時,會向上回溯直到找到name屬性位置。)     中矩形表示特定的環境。其中 內部環境可以通過範圍鏈訪問所有的外部環境,但外部環境不能訪問內部變數環境中的任何變數和函數。這些環境之間的練習是線性,有次序的。每個環境變數都可以向上搜尋範圍鏈,以查詢變數和函數名;反之則是不行。    注意, 函數參數也被當作變數來對待,因此其訪問規則與執行環境中的其他變數相同。1、延長範圍鏈    雖然執行環境的類型總共只有兩種——全域和局部(函數)。但還是可以通過其他方法來 延長範圍鏈。因為有些語句在範圍鏈的前端臨時增加了一個變數對象,該變數對象會在代碼執行後被移除。當執行流進入下列任一語句時,範圍鏈就會得到加長:
  • try-catch語句的catch塊
  • with語句
    這兩個語句都會在範圍鏈前端增加一個變數對象。對於with語句來說,會將指定的對象添加到範圍鏈中。對於catch語句來說,會建立一個新的變數對象,其中包含的是被拋出的錯誤對象的聲明。 2、沒有塊級範圍
if(true){    var color = "blue";}alert(color);
     注意:如果是在C#、java中,color會在if語句執行完畢後被銷毀,但在JavaScript中,if語句中的變數聲明會將變數添加到當前的執行環境中(在這裡是全域執行環境)。在使用for語句時尤其要牢記這一差異,例如
for (var i=0;i<10;i++){    doSonmething(i);}alert(i); //10
     對於C#,java語言來說,for語句初始設定變數的運算式所定義的變數,最會存在於迴圈的環境中。而對JavaScript來說,for語句建立的變數i即使for迴圈結束後,也依舊會存在與迴圈外部的執行環境中。

    在使用var關鍵字聲明變數時,這個變數將被自動添加到最接近的環境中。在函數內部,最接近的環境就是函數的局部環境。在with語句中,最接近的環境是函數環境。所入初始設定變數時沒用用var聲明,該變數會被自動添加到全域環境。

    查詢標識符(變數等),當在某個環境中為了讀取或寫入為引入一個標識符時,就必須通過搜尋來確定該標誌符實際代表什麼。搜尋過程從範圍鏈的前端開始,向上逐級查詢與給定名字匹配的標識符。如果局部變數中有,搜尋停止,如果沒有在逐級向上搜,直到全域環境。如果全域環境中也沒有找到這個標識符,則意味著該變數沒有聲明過。

    通過下面這個執行個體,可以理解查詢標識符的過程:

var color="blue";function getColor(){    return color;}alert(getColor()); //blue

    調用本例中的函數getColor()時會引用變數color。為了確保變數color的值,將開始一個兩步走的搜尋過程。首先,搜尋getColor()的變數對象,尋找其中是否包含一個名為color的標識符。在沒有找到的情況下,搜尋到下一個變數對象(全域環境的變數對象),然後在那裡找到了名為color的標識符。因為搜尋到了定義這個變數對象,搜尋過程也宣告結束。

    在這個搜尋過程中,如果存在一個局部的變數的定義,則搜尋會自動停止,不會再進入外部環境進行搜尋。

 變數查詢也不是沒有代價。很明顯,訪問局部變數要比訪問全域變數快的多,因為不用向上搜尋範圍鏈,但這個差別在將來的最佳化下會變得可以忽略不計。

 

原文:https://www.cnblogs.com/zxj159/archive/2013/05/17/3084598.html

JavaScript之執行環境及範圍

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.