兩道關(guān)于JS的小考題(閉包與中間件)
題目一:寫一個javascript函數(shù) calculate,該函數(shù)有如下性質(zhì)
calculate() = 0; calculate(2)() = 2; calculate(3)(4)(1)(5)() = 13;
即可以連續(xù)地鏈?zhǔn)秸{(diào)用,一旦碰到一次調(diào)用沒有參數(shù)的,則返回前面所有參數(shù)的和。
其實題目本身并不算復(fù)雜,代碼也非常簡單,就是思路有點繞,可能要在電腦上反復(fù)試試調(diào)調(diào)才能寫對,答案如下:
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
主要思路就是用閉包變量記錄當(dāng)前的結(jié)果,所寫的函數(shù)一旦沒有參數(shù),就返回數(shù)字結(jié)果,一旦有一個參數(shù),記錄下當(dāng)前的和,然后返回函數(shù)自己。
題目二:有一個JS函數(shù),函數(shù)名為APP,它滿足如下性質(zhì):
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方法注冊一系列函數(shù),并通過run方法依次把注冊的函數(shù)跑一遍,注冊的函數(shù)都接受一個next函數(shù)作為參數(shù),一旦碰到next執(zhí)行,則遞歸調(diào)用下一個注冊函數(shù)。請寫出APP這個函數(shù)的實現(xiàn)。
剛看到這個題目的時候有點蒙圈,感覺無從下筆,思考了很久以后發(fā)現(xiàn)……原來這么簡單……自己把自己繞進(jìn)去了。答案如下:
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();
};
浙公網(wǎng)安備 33010602011771號