JS的解析與執行過程


<script>

/*

js的解析過程,很有意思的一個東西

*/

//一階段

var a = 5;

function f(n){

  alert(a);

}

f();

/*

上面代碼的全局處理過程:

1、預處理階段

    a、讀取分析整個源代碼

    b、先掃描函數聲明,之后掃描變量(var聲明)

        b_a、處理函數聲明時有沖突,會覆蓋

        b_b、處理變量聲明時有沖突,會忽略

    c、將掃描到的函數和變量保存到一個對象中(全局的保存到window對象中)

    d、變量的值是undefined,函數的值則指向該函數(是一個函數字符串)

           形式如:window = {a : undefined, f : 'function(){alert(a);var a = 5;}'}

2、運行階段

    在我們剛剛的案例中

    a、將變量a的值從undefined改為5

    b、調用f(),以便函數得到執行

上面函數(f)內,代碼的處理過程:

    1、預處理階段

        a、將函數的參數添加到一個對象(暫定為:詞法對象)

        b、掃描函數聲明,之后掃描變量(var聲明)

        d、將掃描到的函數和方法添加到詞法對象里面

        c、變量的值是undefined,函數的值則指向該函數(與全局的一樣)

    2、運行階段

        與全局的的運行原理一樣

*/

//二階段

var b = 1;

function ff(){

  alert(b);

  var b = 5;

  alert(b);

}

ff();

//結果彈出為:undefined, 5

/*

原因:

js在預處理階段時,將函數ff()和變量b保存到window對象中,

此時b = undefined,到了運行階段,b = 1,這時調用函數ff(),

js會先把函數內的變量添加到詞法對象中,此時b = undefined,

再之后alert(b),因為是在方法內部,所以alert(b)會調用詞法

對象中的b。然而這時詞法對象中的b = undefined,所以第一個alert執行結

果彈出的是undefined,當alert執行完之后b = 5,故第二個alert結果是5;

*/

//三階段

alert(a);

function a() {

  console.log("xx");

}

var a = 5;

function a() {

  console.log("yy");

}

//運行結果:'function a() { console.log("yy"); }'

/*

原因:

我們發現變量a和兩個方法a()同名了,這時,js在預處理的時候

會優先將函數保存到window對象中,然后如果發現同名的是

變量,這時它會忽略這個變量;如果發現同名的是函數,那

么后面的會將前面的覆蓋。所以執行alert彈出的會是第二個函數a

*/

/*************************************************************/

alert(b);

var b = 5;

var b = function () {

  console.log("xx");

}

//運行結果:undefined

/*

原因:

我們知道,定義一個函數有多種形式。像上面這個案例中,

我們的函數是匿名的,然后賦值給了一個變量。但變量終究

是變量,js不會因為它的值比較特別就特殊對待,所以,js

在預處理的時候,先將第一個變量b保存到window中,此時

變量b=undefined,然后第二個變量b覆蓋了第一個變量,此時

的變量b依然還是等於undefined,所以在程序運行的時候彈出

值會等於undefined。

*/

function c(num1){

  alert(num1);

}

c(2);

//運行結果:2

function d(num2){

  alert(num2);

  var num2 = 5;

}

d(2);

//運行結果:2

/*

原因:

在運行前,我就猜想彈出的這個應該是一個undefined的

可沒想到卻是2,這使我百思不得其解。於是請教老師得

出答案。

在js預處理的時候讀取到了這個函數有一個參數,於是就

直接將這個參數放到了詞法對象中,這是這個參數的值是

undefined,之后它繼續向下掃描,發現有一個變量定義,

但我們卻發現這變量與參數同名,這個時候js會怎么做?

這時按照之前所學的,這個變量會被加到詞法對象中,而

事實上也的確是加了,不過卻給它打上了一個標簽,用來

標識這個變量是一個參數,這時這個變量的值也是undef-

ined。當程序真正運行的時候,我們把參數傳過去,這個

參數就會賦值的到這個參數中,然后彈出結果,然后再賦

值為5。

接下來還有幾個問題

1.看下面代碼

funciton f(num){

  alert(num);

  funciton num(){
    
  }

}

f(6);

返回結果為:'funciton num(){}'

像出現上面這個情況的時候,js也還是一樣在預處理的時

候,將參數放到詞法對象中,然后發現里面有一個同名的

函數,這時js就會把這個函數放到詞法對象中,並覆蓋之

前的參數,而它的值指向的就是這個函數。當我們程序真

正運行時,我們把參數傳過去,js在這里並不會把6這個參

數值賦值給這個形參。

</script>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM