JavaScript中的事件循環機制跟函數柯里化

一、事件循環機制的理解

test();//按秒輸出5個5

function test() {
    for (var i = 0; i < 5; i++) {
        setTimeout(() => {
            console.log(i);
        }, 1000 * i);//for循環裡面添加非同步操作
    }
}
test();//分別按秒輸出0  1  2  3  4

function test() {
    for (let i = 0; i < 5; i++) {
        setTimeout(() => {
            console.log(i);
        }, 1000 * i);//for循環裡面添加非同步操作
    }
}

首先,先解釋一下產生不同的結果的原因:
我們知道,var跟let的核心區別主要就是作用域的問題。
詳細解釋:
因為let i 聲明的是區塊變數,每個i只能存活到大括弧結束,並不會把後面for循環的 i 值賦給前面的setTimeout中的i;
而var i 則是局部變數,這個 i 的生命周期不受for循環的大括弧限制;

這道面試題還涉及到了JavaScript中的事件循環機制,稍微重點講解一下:
我們知道,JavaScript是單執行緒的(一次只能執行一個任務),那單執行緒是如何做到非同步的呢?
在大學裡,數據結構中,我們學過棧(先進後出)和隊列(先進先出)這兩種數據結構吧。
js引擎中,便用到了,棧中存放執行的程式碼,隊列中存放多個任務
事件循環機制(Event Loop):js會檢查棧中是否為空,為空的話,將隊列中的任務加入到這個棧中。

這樣的話,還是不能實現非同步的,畢竟js是單執行緒,一次只能執行一個任務,即使有棧和隊列,還是不能實現非同步的,那非同步到底是怎麼實現的呢?
這裡需要了解一下回調函數,舉個例子,jQuery中Ajax非同步請求我們經常用到吧,其中的success就是個回調函數。
其實呢,如果是個非同步操作的話,當放入到隊列中後,它會註冊一個回調事件,然後再執行這個回調函數,如此,便實現了非同步。

舉個例子吧:

var x = 6;
console.log(x);
var pro = new Promise(function (reslove, reject) {
    var i = 3;
    setTimeout(() => {
        i++;
        reslove(i);
    }, 3000);
});
pro.then(function (data) {
    console.log(data);
});

分析:前兩行程式碼定義變數便列印出來,接下來便是個非同步操作,便是通過resolve回調函數來真正實現非同步的。

二、函數柯里化

乍一看,給人一種很是高大上的感覺。這東西呢,理解起來真的是雲里霧裡的。
柯里化,是函數式編程裡面的一個概念。
說下初步的理解吧

function add(num1, num2) {
    return num1 + num2;
}
// 柯里化的思想
function curriedAdd(num2) {
    return add(5, num2);
}
console.log(add(2, 3));//5  寫好一個函數,然後在需要的時候調用這個函數。這便是函數式編程的基本思想。
console.log(curriedAdd(3));//8

正如上面的程式碼,本來add方法裡面需要傳遞2個參數,函數柯里化後,類似curriedAdd只需要傳遞1個參數即可。這便是所謂的函數柯里化。當然,這上面並不夠標準,只是表達了柯里化的思想。

function add(num1, num2) {
    return num1 + num2;
}
//柯里化方法
function curry(fn) {
    var args = Array.prototype.slice.call(arguments, 1);
    return function () {
        var innerArgs = Array.prototype.slice.call(arguments);
        var finalArgs = args.concat(innerArgs);
        return fn.apply(null, finalArgs);
    }
}
var curriedAdd = curry(add, 5);//函數柯里化
console.log(curriedAdd(3));//8

那函數柯里化的好處是什麼呢?既然提出了這個概念,沒有好處是不可能滴!
簡單來說就是為了簡便,調用函數的時候,只需傳遞一個參數。當然了,我理解得還不夠深,沒達到那種透徹的地步,仍然有點雲里霧裡的感覺,沒充分地體會到函數柯里化的好處。

總結

發現自己還有很長的一段路要走!鑽的還是不夠深!不夠精!