1. 程式人生 > >js預解析

js預解析

想要 javascrip 解析器 參數傳遞 java 字符 參數 被占用 lar

1. 定義

預解析:在當前作用域下,js運行之前,會把帶有var和function關鍵字的事先聲明,並在內存中安排好。然後再從上到下執行js語句。

預解析只會發生在通過var定義的變量和function上。


2. var

通過var關鍵字定義的變量進行預解析的時候:都是聲明declare,不管它有沒有賦值,都會賦值undefined。

alert(a); //undefined
var a = 1;
alert(b); //undefined
var b = function(){
}
alert(c); //undefined
var c;
只要是通過var定義的,不管是變量,還是函數,都是先賦值undefined,如果是變量,也不管變量有沒有賦值,在預解析階段,都是會被賦值為undefined。

3. function

function進行預解析的時候,不僅是聲明而且還定義(define)了,但是它存儲的數據的那個空間裏面存儲的是代碼是字符串,沒有任何意義。

alert(a); //彈出的是下面的function
function a(){
  alert("預解析function")
}
註意這種情況

定義一個函數想要立即執行,寫成如下形式是不可行的,在預解釋的時候,它把它分解成兩部分來對待,第一部分是fn函數,而第二部分是(),一個匿名函數,執行時會報錯。如果小括號帶參數,如(2),雖然不會報錯,會打印出來2,但並不能把fn執行,也不能當成參數傳遞給fn函數。

function fn(){
//代碼區
}()
如果你想實現立即執行的函數,可以把要執行的函數放到一對括號裏面,對於JavaScript 來說,括弧()裏面不能包含語句,所以在這一點上,解析器在解析function關鍵字的時候,會將相應的代碼解析成function表達式,而不是function聲明所以,只要將大括號將代碼(包括函數部分和在後面加上一對大括號)全部括起來就可以了。 如下:

(function fn(){
//代碼區...
}())
還可以寫成:閉包。

(function(){
//代碼區...
})();
4. 預解析需要註意的情況

預解析是發生在當前作用域下的,剛開始的時候,我們預解析的是全局作用域,在js中我們的global就是我們的window。
我們運行函數的時候會生成一個新的私有作用域(每次執行都是新的,執行完成就銷毀)這個作用域下我們可以理解為開辟了一個新的內存空間。在這個內存中我們也要執行預解析。當我們的函數執行完成後,這個內存或者作用域就會銷毀
如果在當前作用域下的一個變量沒有預解析,就會向它的上一級去找,直到找到window,如果window下也沒有定義,就會報錯。所以,在函數內通過var定義的變量是局部變量,沒有能過var 定義的變量是全局變量。
預解析不會在同一個變量上重復的發生,也就是一個變量如果已經在當前作用域下預解析了,不會再重復解析。
等號右邊的function不會進行預解析。
alert(a);
fn();
var a = function fn(){};
第一次打印undefined,第二次報錯,未定義,因為預解析的時候,=號右邊是不進行預解析的。

預解釋是不受其它if或者其它判斷條件影響的,也就是說,即使條件不成立,我們裏面只要有var或者function也會被預解釋。if,while
alert(a); //undefined
if(1==2){
  var a=12;
}
後面定義的會覆蓋前面定義的
alert(a); //彈出後面的function
function a(){
var b;
}
alert(a); //仍然彈出後面的function,因為function是提前預解析的
function a(){
var c;
}
JavaScript“預解析”是分段進行的,準確說是分<script>塊進行的。

5. 測試題

題目一:

if(!("a" in window)){
var a = "李玉華";
}
alert(a);
題目二:

function fn(){
alert("我們是全局的fn");
}
function fn2(){
alert(fn);
fn = 3;
return ;
function fn(){
alert("我是fn2裏面的");
}
}
fn2(); //function fn(){alert("我是fn2裏面的");}
我們的預解釋也不會受到function裏面的return影響

題目三:

var n = 0;
function a(){
var n = 10;
function b(){
n++;
alert(n);
}
b();
return b;
}
var c = a(); //a()執行一次,彈出11,並且把返回值賦給c,此時的c為function b(){}
c(); //alert(n),12
alert(n); // 0
題目四:

return直接返回的那個,其實是一個結果或者是值,是不需要預解釋的。

var n = 99;
function outer(){
var n = 0;
return function inner(){
return n++;
}
}
var c = outer(); //c=function inner(){ return n++; }
var num1 = c(); //0,然後再執行n++ 此時n=1;
var num2 = c(); //1, n++ 2;
var d = outer(); //重新開辟新
var num3 = d(); //0
當我們的一個函數返回一個新的function,我們在外面定義一個變量來接收,這樣這個函數的內存就不能在執行完成後自動銷毀,也就是我們所謂的函數內存被占用了。

變量的值要看它在哪定義,this,要看它在哪調用的。

js預解析