1.執行環境
執行環境有全局執行環境(也稱全局環境)和函數執行環境之分。
執行環境如其名是在運行和執行代碼的時候才存在的,所以我們運行瀏覽器的時候會創建全局的執行環境,在調用函數時,會創建函數執行環境。
1.1全局環境
全局執行環境是最外圍的一個執行環境,在web瀏覽器中,我們可以認為他是window對象,因此所有的全局變量和函數都是作為window對象的屬性和方法創建的。代碼載入瀏覽器時,全局環境被創建,關閉網頁或者關閉瀏覽時全局環境被銷毀。
1.2函數執行環境
每個函數都有自己的執行環境,當執行流進入一個函數時,函數的環境就被推入一個環境棧中,當函數執行完畢后,棧將其環境彈出,把控制權返回給之前的執行環境。
2 作用域、作用域鏈
2.1 全局作用域(globe scope)和局部作用域(local scope)
全局作用域和局部作用域中變量的訪問權限,其實是由作用域鏈決定的.
每次進入一個新的執行環境,都會創建一個用於搜索變量和函數的作用域鏈。
作用域鏈是函數被創建的作用域中對象的集合。
作用域鏈可以保證對執行環境有權訪問的所有變量和函數的有序訪問。
作用域鏈的最前端始終是當前執行的代碼所在環境的變量對象(如果該環境是函數,則將其活動對象作為變量對象),下一個變量對象來自包含環境(包含當前還行環境的環境),下一個變量對象來自包含環境的包含環境,依次往上,直到全局執行環境的變量對象。全局執行環境的變量對象始終是作用域鏈中的最后一個對象。
1.函數的局部環境可以訪問函數作用域中的變量,也可以訪問和操作父環境(包含環境)乃至全局環境中的變量。
2.父環境只能訪問其包含環境和自己環境中的變量和函數,不能訪問其子環境中的變量和函數。
3.全局環境只能訪問全局環境中的變量和函數,不能直接訪問局部環境中的任何數據。
3.作用域提升
3.1 變量提升
var name="haha"; 2 function changeName(){ 3 console.log(name); 4 var name="xixi"; 5 } 6 changeName(); 7 console.log(name); 輸出:undefined 和 haha
var name="haha"; 2 function changeName(){ 3 var name; 4 console.log(name); 5 name="xixi"; 6 } 7 changeName(); 8 console.log(name); 相當於上面代碼的解釋,變量提升
3.2函數提升
在JavaScript中函數的創建方式有三種:函數聲明(靜態的,像函數example1()的形式)、函數表達式(函數字面量)、函數構造法(動態的,匿名的)。
函數表達式:
var func1 = function(n1,n2){ 2 //function body; 3 };
函數構造法:
var func2 = new Function("para1","para2",...,"function body");
函數聲明:
//函數聲明 function myTest1(){ func(); function func(){ console.log("我可以被提升"); } } myTest1();
輸出:我可以被提升 //函數表達式 function myTest2(){ func(); var func = function(){ console.log("我不能被提升"); } } myTest2();
輸出:object expected