衆所周知,JavaScript是動態類型語言,比較靈活,經常存在一些使人的頭疼的地方。面試
例如:bash
var a = 10 ;
閉包
add()
函數
function add() {
ui
return a + b;
spa
};
code
var b = 1;
cdn
結果輸出NaN ;
blog
這就很使人頭疼,下面咱們來解釋下爲何會出現這種狀況吧。three
JavaScript是解釋型語言,解釋一行執行一行,也能夠理解爲讀取一行執行一行(一行一行執行就對了)
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代碼執行順序的順序。
好了,下面咱們來點面試題吧,相信你們也常常被這些面試題坑。
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);
複製代碼
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;
複製代碼
可能你們仍是以爲很簡單,那咱們在加大難度。
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
固然還能夠在難一點,但是樓主飛機誤點了,一直在等飛機😭 深圳這該死的 ☁️
有更好的面試題的小夥伴能夠子啊下面留言告訴我呦,一同進步