JavaScript與解析不一樣狀況分析

要寫出嚴謹的代碼或者是優化性能就必須作到‘知己知彼’,爲此把握事物規律方能有備無患,穩步前進,故對此有所探知。函數

1、階段

var a = 5;

function f(n){

  alert(a);

}

f();

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

一、預處理階段優化

a、讀取分析整個源代碼

b、先掃描函數聲明,以後掃描變量(var聲明)

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

    b_b、處理變量聲明時有衝突,會忽略(相對函數聲明)

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

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

   形式以下:{a : undefined, f : 'function(){alert(a);}'}

二、運行階段code

在咱們剛剛的案例中

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

b、調用f(),一遍函數獲得執行

上面函數代碼的處理過程:對象

**一、預處理階段**

    a、將函數的參數添加到一個對象(**詞法對象**)

    b、掃描**函數聲明**,以後掃描變量(var聲明)

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

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

二、運行階段

    與全局的的運行原理同樣

2、階段

var b = 1;
    
    function ff(){
    
      alert(b);
    
      var b = 5;
    
      alert(b);
    
    }
    
    ff();

//結果彈出爲:undefined

緣由:ci

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

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

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

再以後alert(b),由於是在方法內部,因此alert(b)會調用詞法console

對象中的b。然而這時詞法對象中的b = undefined,因此執行結

果彈出的是undefined,當alert執行完以後b = 5;

3、階段

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彈出的會是函數

4、階段

alert(b);

var b = 5;

var b = function () {

  console.log("xx");

}

//運行結果:undefined

緣由:

咱們知道,定義一個方法有多種形式。像上面這個案例中,

咱們的函數是匿名的,而後賦值給了一個變量。但變量終究

是變量,js不會由於它的值比較特別就特殊對待,因此,在

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

變量b=undefined,而後第二個變量b覆蓋了第一個變量,此時

的變量b依然仍是等於undefined,因此在程序運行的時候彈出

值會等於undefined。

5、階段

function c(num1){

  alert(num1);

}

c(2);

//運行結果:2

function d(num2){

  alert(num2);

  var num2 = 5;

}

d(2);

//運行結果:2

緣由:

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

可沒想到倒是2,這使我百思不得其解。

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

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

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

但咱們卻發現這變量與參數同名,這個時候js會怎麼作?

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

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

標識這個變量是一個參數這時這個變量的值也是undefined

當程序真正運行的時候咱們把參數傳過去,這個參數就會賦值的到這個參數中

而後彈出結果,而後再賦值爲5。

6、階段

接下來還有幾個問題

1.看下面代碼

funciton f(num){

  alert(num);

  funciton num(){
    
  }

}

f(6);

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

像出現上面這個狀況的時候,js也仍是同樣在預處理的時

候,將參數放到詞法對象中,而後發現裏面有一個同名的

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

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

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

數值賦值給這個形參。

相關文章
相關標籤/搜索