前 言javascript
LiuDaPjava
今天就給你們介紹一個特別基礎的東西,javascript中函數的一點兒小知識(js代碼的執行順序),但願對你們有那麼一點點幫助吧!!!
多線程
1、js--->單線程 |
嚴格意義上來講,javascript沒有多線程的概念,全部的程序都是單線程依次執行的。函數
一、什麼是單線程?spa
通俗點說,就是代碼在執行過程當中,另外一段代碼想要執行就必須等當前代碼執行完成後才能夠進行。咱們拿一段代碼來解釋一下吧線程
1 for(var i=1;i<=3;i++){ 2 setTimeout(function(){ 3 console.log(i); //輸出:4,4,4 4 },0) 5 }
咱們來看一下上面的這段代碼,既然延時器時間設置爲0,那麼應該執行一遍循環就應該當即打印出一個i,可是最終的打印結果爲:4,4,4。之因此會出現上面的結果,正是由於js代碼是單線程應用。code
在執行過程當中,先遇到for循環,for循環先進入線程。當i=1時,循環走到setTimeOut後,此時的for循環尚未執行完成,setTimeOut就會被放入一個地方(線程池)等待執行。此時for循環繼續執行,當i=2時,for循環仍沒有執行完,這時的setTimeOut仍會被放在線程池中等待執行……依次類推,直到for循環轉完3遍後,for循環執行完了,此時線程空閒了,在線程池中等待執行的setTimeOut依次執行打印i,而for循環執行完成後,i變成了4,因此打印出了三個4。對象
二、若是想要改變上面的情況能夠運用如下代碼blog
//將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) }
2、js中的函數做用域和代碼的執行 |
咱們先來了解一下如下幾個概念:ip
一、在js語言中,沒有相似於c語言這樣的塊級做用域。
二、js語言中的頂級做用域爲window對象範圍內,稱爲全局做用域,在全局做用域中聲明的變量爲全局變量。
三、js函數範圍內的變量只能在函數內部使用,函數外部沒法使用,這樣的變量爲局部變量。
四、js函數能夠嵌套,多個函數的嵌套構成了做用域的層層嵌套,這稱爲js中的做用域鏈。
五、js做用域鏈變量訪問規則:
(1)、當前做用域內存在要訪問的變量時,則使用當前做用域中的變量。
(2)、當前做用域中不存在要訪問的變量時,則會到上一層做用域中尋找,直到全局做用域。
js代碼執行分爲兩個部分:
一、代碼的檢查裝載階段(預編譯階段),此階段進行變量和函數的聲明,可是不對變量進行賦值,變量的默認值爲undefined。
二、代碼的執行階段,此階段對變量進行賦值和函數的聲明。
看了上面的一些具體的概念,咱們拿一段代碼進行舉例說明:
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。
這個週末因爲事情太多了,就給你們分享到這裏吧,但願這一點點小知識能給你們帶來一點點的幫助。。