在開發語言中常見的作用域規則有 塊級作用域和詞法作用域
作用域 顧名思義就是起作用的區域 定義一變量後 ,可以在此范圍作用的區域
一、塊級作用域就是用一個塊結構分割變量的訪問區域 塊即{ } 代表語言有C 系列語言
二、詞法作用域就是變量的作用范圍,在書寫代碼時就已經決定作用的范圍,與運行時無關
特點:分割作用域只有函數
變量名提升
函數名提升
函數的聲明比變量的聲明優先級高
function a(){ } var a; alert(a);//打印出a的函數體 var a; function a(){ } alert(a);//打印出a的函數體 //但是要注意區分和下面兩個寫法的區別: var a=1; function a(){ } alert(a);//打印出1 <script> function a(){ } var a=1; alert(a);//打印出1
function test() { bar(); // 2 var foo = function () { // 變量指向函數表達式 console.log("1"); } function bar() { // 函數聲明 函數名為bar console.log("2"); } foo();//1 } test(); 但是 function test() { foo();//報錯 bar(); var foo = function () { // 變量指向函數表達式 console.log("1"); } function bar() { // 函數聲明 函數名為bar console.log("2"); } } test();
結論
1、聲明會提升
2、 只有函數才會限定作用域
繪制作用域鏈規則
1> 將全部的 script 標簽看做一個整體. 是一個 0 級別的鏈
鏈中所有的全局范圍內的變量, 函數, 對象... 都是鏈中的成員
由於聲明會提升, 因此在繪制鏈之前將代碼可以進行調整, 在開始的時候
將聲明都寫在前面, 繪圖的時候按照順序繪制, 較為簡單.
2> 由於只有函數才可以限定作用域. 因此在函數上引出一條新鏈, 級別為 n + 1
在函數內部, 又是一個完整, 獨立的作用域結構
因此在函數內部定義的任何成員也按照 1> 中的規則在該鏈上展開
3> 如果有函數, 繼續繪制下去
變量搜索原則
在代碼的運行過程中, 如果訪問某一個變量
那麼首先在當前鏈上找 ( 無序 ), 如果沒有, 在 n-1 級上找
( 在函數內部允許訪問定義在函數外部的變量 )
如此往復, 直到 0 級鏈, 如果還沒有 拋出異常
如果找到, 則結束尋找, 直接獲得該鏈上變量的數據