開始之前
由於本人也是JavaScript初學者,記錄學習經過,怕以后會忘記。
對於JavaScript 初學者來說,最難的不是代碼部分,而是對很多書籍中的術語的理解,大多時候想要理解一段JavaScript書籍中的解釋內容,就會涉及很多術語,在術語不通的情況下都會對內容理解偏差(導致很難記住所學內容),由於本人在閱讀書籍時經常會遇到這一問題,所以今天將記下這一基礎內容。
一、需要關注點
1)執行環境(作用域)函數執行環境 變量作用域
2)函數作用域和聲明提前
3)自由變量
4)詞法作用域和靜態作用域
5)動態作用域
二、解釋
1)執行環境(作用域)變量作用域
說到執行環境這個詞,對於看過JavaScript高級程序設計的同學並不陌生,那么我們就先來看看什么是執行環境:
1.執行環境:簡稱:“環境”,是JavaScript中最重要的一個概念。執行環境定義了變量或函數有權訪問的其他數據,決定了它們各自的行為,每個執行環境都有一個與之關聯的“變量對象(variable object)”,環境中定義的所有變量和函數都保存在這個對象中。我們編寫的代碼是無法訪問這個對象的,但解析器在處理數據時會在后台使用它。
2.全局執行環境是最外圍的一個執行環境,在Web瀏覽器中,全局執行環境被認為是window對象,因此所有全局變量和函數都是作為window對象的屬性和方法來創建的。某個執行環境中的所有代碼執行完畢后,該環境就會被銷毀,保存在其中的所有變量和函數定義也隨之銷毀。
3.函數執行環境:每個函數都有自己的執行環境,當執行流進入一個函數時,函數的環境就會被推入一個環境棧中。而在函數執行之后,棧將其環境彈出,把控制權返回給之前的執行環境。
4.作用域鏈:它的用途是保證對執行環境有權訪問的所有變量和函數的有序訪問,作用域鏈的前端,始終都是當前執行的代碼所在的環境的變量對象。當代碼在一個執行環境中執行時,會創建變量對象的一個作用域鏈(scope chain)。
2)聲明提前
1.聲明提前:javascript的函數作用域是指在函數內聲明的所有變量在函數體內始終是可見的,這意味着變量在聲明之前是可用的,這也是原因。這步操作是在javascript "預編譯"時進行的,是在代碼運行之前。
// 局部變量優先於全局變量 // 函數嵌套的情況下,最內層函數變量優先於在它之上的函數變量 var scope = 'global scope'; function checkScope() { // body... var scope = 'local scope'; function nested() { var scope = 'nested scope'; return scope; } return nested(); } var scope = checkScope(); console.log('varable scope :', scope) // 'nested scope'
3)自由變量:在A作用域中使用的變量x,卻沒有在A作用域中聲明(即在其他作用域中聲明的),對於A作用域來說,x就是一個自由變量。
ar x = 10; function fn(){ var b = 20; console.log(x + b); // x 就是一個自由變量。 }
4)詞法作用域和靜態作用域:詞法作用域等同於靜態作用域,靜態作用域規則查找一個變量聲明時依賴的是源程序中塊之間的靜態關系;
5)動態作用域規則依賴的是程序執行時的函數調用順序。
靜態作用域和動態作用域的一個重要區別在於:
靜態作用域規則查找一個變量聲明時依賴的是源程序中塊之間的靜態關系;
而動態作用域規則依賴的是程序執行時的函數調用順序。
說的具體點,就是靜態作用域查找的是距離當前作用域最近的外層作用域中同名標識符的聲明,
而動態作用域則是查找最近的活動記錄
JavaScript 是使用詞法作用域。
關於作用域幾篇比叫好的文章:
http://www.cnblogs.com/zxj159/archive/2013/05/17/3084598.html
http://www.cnblogs.com/wangfupeng1988/p/3992795.html