javascript是由瀏覽器解釋執行的腳本語言,不同於java c,需要先編譯后運行,javascript 由瀏覽器js解釋器進行解釋執行,總的過程分為兩大塊,預編譯期和執行期
下面的幾個demo解釋了js解釋器對變量和代碼的解釋過程
//#demo1 foo();//alert(1) function foo(){//聲明式函數 alert(1); } foo2();//undefined is not a function var foo2 = function(){//賦值式函數聲明,其實是函數表達式 alert("foo2"); }; //#demo2 alert(str);//undefined var str="str"; alert(str);//str
js執行過程分為與編譯期和執行期(以代碼塊為單位,邊解釋邊執行),在預編譯期,js解釋器會對本代碼段內所有的 聲明的變量和方法進行處理,將變量和方法提到對應的作用域的最前面,該過程只是對變量進行聲明,並不會進行初始化或者賦值(缺省值默認為undefined)
//#demo1中聲明式函數與賦值式函數區別在於 聲明式函數會在預編譯期被整體提到作用域前面,所以其實#demo1經過預編譯后代碼如下:
var foo2; //缺省值是'undefined' function foo(){ alert(1); } foo(); foo2();//undefined is not a function foo2 = function(){ alert('foo2'); };
JavaScript 中局部變量只可能通過兩種方式聲明,一個是作為函數參數,另一個是通過 var 關鍵字聲明。 var 表達式和 function 聲明都將會被提升到當前作用域的頂部,看一下#demo3
bar(); var bar = function() {}; var someValue = 42; test(); function test(data) { if (false) { goo = 1; } else { var goo = 2; } for(var i = 0; i < 100; i++) { var e = data[i]; } }
上面代碼在運行之前將會被轉化。JavaScript 將會把 var 表達式和 function 聲明提升到當前作用域的頂部。
var bar,someValue; function test(data){ var goo,i,e; if(false){ goo = 1; } else{ goo = 2; } for(i=0;i<100;i++){ e = data[i]; } } bar();//undefined bar = function(){}; someValue = 42; test();
當訪問函數內的 goo 變量時,JavaScript 會按照下面順序查找:
1.當前作用域內是否有 var goo的定義。 2.函數形式參數是否有使用 goo名稱的。 3.函數自身是否叫做 goo。 4.回溯到上一級作用域,然后從 #1 重新開始