javascript代碼執行順序問題

1、什麼是單線程?

通俗點說,就是代碼在執行過程中,另一段代碼想要執行就必須等當前代碼執行完成後才可以進行。我們拿一段代碼來解釋一下吧

for(var i=1;i<=3;i++){

setTimeout(function(){

console.log(i); //輸出:4,4,4

},0)

}

我們來看一下上面的這段代碼,既然延時器時間設置為0,那麼應該執行一遍循環就應該立即打印出一個i,但是最終的打印結果為:4,4,4。之所以會出現上面的結果,正是因為js代碼是單線程應用。

在執行過程中,先遇到for循環,for循環先進入線程。當i=1時,循環走到setTimeOut後,此時的for循環還沒有執行完成,setTimeOut就會被放入一個地方(線程池)等待執行。此時for循環繼續執行,當i=2時,for循環仍沒有執行完,這時的setTimeOut仍會被放在線程池中等待執行……依次類推,直到for循環轉完3遍後,for循環執行完了,此時線程空閒了,在線程池中等待執行的setTimeOut依次執行打印i,而for循環執行完成後,i變成了4,所以打印出了三個4。

2、如果想要改變上面的狀況可以運用以下代碼

//將var變為let

for(let i=1; i<=3; i++){

setTimeOut(function(){

console.log(i); //輸出的結果為1,2,3

},0);

}

//用自執行函數進行包裹

for(var i=1; i<=3; i++){

!function(i){

setTimeOut(function(){

console.log(i); //輸出的結果為1,2,3

},0);

}(i)

}

二、js中的函數作用域和代碼的執行

>>>函數作用域

我們先來了解一下以下幾個概念:

1、在js語言中,沒有類似於c語言這樣的塊級作用域。

2、js語言中的頂級作用域為window對象範圍內,稱為全局作用域,在全局作用域中聲明的變量為全局變量。

3、js函數範圍內的變量只能在函數內部使用,函數外部無法使用,這樣的變量為局部變量。

4、js函數可以嵌套,多個函數的嵌套構成了作用域的層層嵌套,這稱為js中的作用域鏈。

5、js作用域鏈變量訪問規則:

(1)、當前作用域內存在要訪問的變量時,則使用當前作用域中的變量。

(2)、當前作用域中不存在要訪問的變量時,則會到上一層作用域中尋找,直到全局作用域。

>>>執行順序

js代碼執行分為兩個部分:

1、代碼的檢查裝載階段(預編譯階段),此階段進行變量和函數的聲明,但是不對變量進行賦值,變量的默認值為undefined。

2、代碼的執行階段,此階段對變量進行賦值和函數的聲明。

看了上面的一些具體的概念,我們拿一段代碼進行舉例說明:

var a=1; //聲明瞭一個全局變量

function func(){

console.log(a); //輸出:undefined。打印a,而在func這個作用域中已經聲明瞭a變量,按照js的執行順序,此時的a並未被賦值。

var a=1;

console.log(a); //輸出:1。

}

func();

看上面的代碼:第一個a輸出undefined。原因:js作用域鏈的訪問規則,當前作用域內存在要訪問的變量a,所以使用當前作用域中的變量。再根據js代碼的執行順序,此時的a只是聲明瞭而並未被賦值,默認為undefined,所以輸出undefined。

而第二個a,輸出1,正是因為此時的a已經被聲明且被賦值,所以a輸出1。

以上所述是小編給大家介紹的JavaScript代碼執行的先後順序問題,希望對大家有所幫助,對IT行業感興趣的網友可以關注我們公眾號:九雲IT教育 瞭解更多詳情!


分享到:


相關文章: