變量作用域&函數作用域


一. 變量作用域

1)全局變量

      在全局環境下聲明的變量被視為全局變量。

      在沒有使用var進行聲明的時候,變量就被定義為全局變量。在ES5的嚴格模式下,如果變量沒有使用var來聲明是會報錯的。

2)局部變量

      在函數體內部聲明的變量被視為局部變量。其中涉及到js中的函數作用域問題。

二. 函數作用域

      因為js中是沒有塊級作用域的概念,所謂的塊級作用域就是指花括號內的的每一段代碼都有其自己的作用域,但js中並不是,例如for循環中定義的變量,外界也可以訪問;但是js中有函數作用域的概念,即在每一個函數體內,變量是有其自己的作用域的,外界訪問不到;

三. 變量提升

      js在編譯階段有個特性,就是變量提升。當js引擎在解析代碼的時候,會將變量聲明提升至其函數體的頂部。有關資料可參考

http://www.slideshare.net/lijing00333/javascript-engine

借用ppt里的例子:

a();
function a () {
    alert('Tom' );
}
var a = function () { 
alert(
'Jim');
}

a();

執行時會先彈出Tom,再彈出Jim。具體的過程是,js是解釋型語言,因此當瀏覽器運行js時會分為兩個部分,首先預編譯全部代碼,之后執行代碼。

image

image

下面的例子:

a();
function a () {
   alert('1');
}
a();
function a () {
   alert('2');
}
a();
var a = function () {
   alert('3');
}
a();

此處同理,會彈出2,2,2,3,只不過在編譯階段,后面的函數a聲明覆蓋了前面的聲明,因此在執行a的階段彈出2。最后的3是因為在此函數被調用前對它進行了賦值操作,覆蓋了前面的函數聲明。

四. 函數解析

      (這個地方我理解的也不是特別透徹,僅此拙見,望指正)

      1)Execution context(執行上下文)

每個函數或者全局代碼都會產生一個執行上下文,並在其中運行,而執行上下文的形式是一個object。其中包含

Execution context is an object which consists of:

  • variable object, which is activation object in case of functions
  • scope chain, which you can think of as a linked list of outer scopes
  • this value

      2)變量對象

每個執行上下文都包含一個變量對象,這個變量對象是用來存儲執行環境中的變量和函數聲明,但不同的情況下,包含的數據不同。

Variable object is an abstract thing, which can be either one of those:

  • global object (in global context) - the place where global vars (like window, document or console in a browser) reside
  • activation object (for functions, which define scopes in ECMAScript)

函數表達式不包含在變量對象中

image

image

      3)活動對象

當進入函數執行環境時,會產生一個活動對象(activation object)[在作用域鏈最前端的對象],包含了形參,arguments對象。它作為執行環境的變量對象,除了函數聲明和變量名稱還增加了形參和arguments對象。

Activation object is an object which holds:

  • formal args of the function
  • arguments object for this function
  • any vars and (named) functions inside this function

So, activation object is just a special case of variable object.

It is basically a container for all the local stuff you can access by name inside a function, except for this.image

針對於foo函數,它的活動對象包含下面的內容。

image

4)作用域鏈

在每個執行上下文中都會包含一個作用域鏈,用以存儲函數作用域內的變量和函數聲明和父級變量。當解析一個標識符(函數,形參,變量)的時候會從作用域鏈的變量對象開始查找,一級一級向上查找,類似於原型鏈的概念。

image

image

 

參考:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM