兩道關於JS的小考題(閉包與中間件)

題目一:寫一個javascript函數 calculate,該函數有以下性質javascript

calculate() = 0;
calculate(2)() = 2;
calculate(3)(4)(1)(5)() = 13;

便可以連續地鏈式調用,一旦碰到一次調用沒有參數的,則返回前面全部參數的和。java

其實題目自己並不算複雜,代碼也很是簡單,就是思路有點繞,可能要在電腦上反覆試試調調才能寫對,答案以下:閉包

var calculate = (function () {
    var sum = 0;
    var func = function () {
        if (arguments.length === 0) {
            var ret = sum;
            sum = 0;
            return ret;
        }
        sum += arguments[0];
        return func;
    };
    return func;
})();

console.log(calculate()); // 輸出0
console.log(calculate(100)()); // 輸出100
console.log(calculate(1)(2)(3)(4)()); // 輸出10

主要思路就是用閉包變量記錄當前的結果,所寫的函數一旦沒有參數,就返回數字結果,一旦有一個參數,記錄下當前的和,而後返回函數本身。函數

 

題目二:有一個JS函數,函數名爲APP,它知足以下性質:this

var func1 = function (next) {
    console.log('func1 begin');
    next();
    console.log('func1 end');
};

var func2 = function (next) {
    console.log('func2 begin');
    next();
    console.log('func2 end');
};

var func3 = function (next) {
    console.log('func3 begin');
    next();
    console.log('func3 end');
};

var a = new APP();
a.use(func1);
a.use(func2);
a.use(func3);
a.run();

// output:
// func1 begin
// func2 begin
// func3 begin
// func3 end
// func2 end
// func1 end

有點相似於中間件同樣,APP實例化之後,能夠用use方法註冊一系列函數,並經過run方法依次把註冊的函數跑一遍,註冊的函數都接受一個next函數做爲參數,一旦碰到next執行,則遞歸調用下一個註冊函數。請寫出APP這個函數的實現。prototype

剛看到這個題目的時候有點蒙圈,感受無從下筆,思考了好久之後發現……原來這麼簡單……本身把本身繞進去了。答案以下:中間件

var APP = function() {
    this.stack = [];
};
APP.prototype.use = function (cb) {
    this.stack.push(cb);
};
APP.prototype.run = function() {
    var self = this;

    var next = function () {
        if(self.stack.length < 1) {
            return;
        }
        var cb = self.stack.shift();
        cb(next);
    };
    next();
};
相關文章
相關標籤/搜索