題目一:寫一個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(); };