「javscript-預編譯」

衆所周知,JavaScript是動態類型語言,比較靈活,經常存在一些使人的頭疼的地方。面試

例如:bash

var a = 10 ;
閉包

add()函數

function add() {    ui

    return  a + b;spa

};code

var b = 1;cdn


結果輸出NaN ;blog

這就很使人頭疼,下面咱們來解釋下爲何會出現這種狀況吧。three

1,JavaScript 語言類型

JavaScript是解釋型語言,解釋一行執行一行,也能夠理解爲讀取一行執行一行(一行一行執行就對了)

2,預編譯階段

var 申明的變量會存在變量提高過程,函數也會存在這種狀況 。提高能夠分爲全局變量,函數提高,和局部變量,函數提高(⚠️注意,變量提高優於函數提高!)

下面咱們來看下題目執行順序

首先預編譯,

變量提高,

var a  = undefind;

var b = undefind;

其次函數提高,

function add () {}

變量函數提高完以後開始計算機系統開始讀取代碼,第一行,解釋一行。

首先執行第一行

var a = undefind ; => var a  = 10;           //解釋第一行代碼時發現變量被賦值 

add();                                       //解釋函數,去找函數

function add () {                            //執行函數內部函數

     return a + b ;                          //此時 a = 10;b = undefind; 

}                                            //結束add()函數,Number ➕ undefind = NaN; 

var b = undefind ; => var b = 1;            //發現變量 b 被賦值

以上就是預編譯和JavaScript代碼執行順序的順序。

好了,下面咱們來點面試題吧,相信你們也常常被這些面試題坑。

3,面試題start 

3-1 : 簡單使用

var one = 1 ;

var two = 2 ;

function sum () {
    var three =  3 ;  
    
    two = two + three;

    return one + three
};

var newSum = new Sum();

console.log(newSum);複製代碼

相信你們看過前面的講解就會當即能夠想到結果, 沒錯答案是6 ;

咱們來看下執行順序吧。

//首先變量,函數提高

var one = undefind;

var two = undefind;

var newSum = undefind;

function sum() {};

//開始讀取並解釋JavaScript

var one = undefind => var one = 1;

var two = undefind => var two = 2;

function sum () {
    // ⚠️ 函數內部也會存在變量和函數提高
    var three = undefind; => var three = 3;
    
    /*

        two 被從新賦值,這裏還有一個知識點,當函數
        
        內部找不到變量,會向上一層找,一直找到window上,

        若是找不到就是undefined,因此在函數內存查找two

        找不到,會向上一層查找,在全局變量中找到two和one

    */

    two = 2 => two = 2 + 3;    

    return one + two;          //one = 1,two = 2, 輸出3

}
//函數sum()的值爲3,因此 newSum = 3 ;var newSum = undefind; => var newSum = new sum();  

console.log(newSum);   => console.log(3);  

複製代碼

3-2 : 進階版本

var a = 1;

var b = 2;

function add () {

    var c = 3;

    return a + b;

}

var sum = new add();

console.log(sum);

console.log(c);複製代碼

你們能夠思考下會打印什麼,先來過程吧

//預編譯,變量,函數提高

var a = undefind;

var b = undefind;

var sum = undefind;

function add () {};

//讀取解釋代碼

var a = undefind; => var a = 1;

var b = undefind; => var b = 2;

function add () {
    
    var c = undefind;  => var c = 3;

    return a + b ;    =>  1 + 2;

}

var sum = undefind; => var sum = new add(); //var sum = 3;

console.log(sum)   //  3

//這裏涉及到一個新知識點,c屬於局部變量,全局變量沒法訪問訪問局部變量

//固然有一種方法能夠訪問,那就是閉包了😄

console.log(c)     //  c is not defind;
複製代碼

可能你們仍是以爲很簡單,那咱們在加大難度。


3-3 : 稍高難度版本

var a = 1 ;

var b = 2;

var i = 0;



function add() {
    
    for (;i < b ; i++) {    (function (f) {
            console.log(f)
        })(i)
     };

    return a + i;
}

console.log(i);複製代碼

這個算是難度加大版本的了,小夥伴們能夠思考下,結果是什麼

咱們來看下過程

//預編譯,變量函數提高 ⚠️ 預編譯階段僅僅只有函數和變量存在提高!

var a = undefind;

var b = undefind;

var i = undefind;

function add() {}

//讀取解釋JavaScript

var a = undefind; => var a = 1;

var b = undefind; => var b = 2;

var i = undefind; => var i = 0;

function add () {
    //在函數內部沒法找到 i 與 b  向上一層查找
    for(;i < b ; i++) {

        //當即執行函數,避免 i 提早變量賦值,

        // 一樣用let也能夠避免這樣的事情發生

        (function(f){
            
            // 當即執行函數和let造成暫時性死區效果同樣,依次

            //打印 0 => 1
        
            console.log(f)

        })(i)
    
        //等等,你真的覺得執行完了嗎?i < b 當這個條件執行完,i被賦值爲2,不要忘記這個小細節哦
    }  
  
}

console.log(i);   // i 被從新賦值,打印2複製代碼

因此結果依次爲 0 ,1 ,2  

固然還能夠在難一點,但是樓主飛機誤點了,一直在等飛機😭  深圳這該死的 ☁️ 

有更好的面試題的小夥伴能夠子啊下面留言告訴我呦,一同進步

相關文章
相關標籤/搜索