blog-md
blog-md copied to clipboard
小米的两道闭包面试题
小米的两道闭包面试题 有点意思~
网上看到了这两道题,都挺有意思的,记录~
repeat 函数
// 题目要求!
function repeat (func, times, wait) {
}
// 这个函数能返回一个新函数,比如这样用
var repeatedFun = repeat(alert, 10, 5000)
调用这个 repeatedFun ("hellworld")
会alert十次 helloworld, 每次间隔5秒
网上给的是 setInterval 的写法,不过考虑到 setInterval 返回值容易忽忽悠悠,还是用 setTimeout来写。
function repeat(func, times, wait) {
return function () {
var num = 0;
// 保存传参, 以便在 handler 中使用
var _arguments = arguments
function handler() {
// 注意此处次数
if (num < times) {
num++
func.apply(null, _arguments)
setTimeout(handler, wait)
}
}
setTimeout(handler, wait)
}
}
这个题考察了闭包和 setTimeout 模拟 setInterval 的用法,因为最终要在 handler 方法中执行func,所以要保存 arguments 对象以便下面的闭包函数调用。
次数也踩了坑,递归调用一定要注意终止条件,本来 num++写在 if 之外,觉得不太妥当,还是放在里面。
stringconcat 函数
// 题目要求!
var result1 = stringconcat("a", "b") //result1 = "a+b"
var stringconcatWithPrefix = stringconcat.prefix("hellworld");
var result2 = stringconcatWithPrefix("a", "b") // result2 = "hellworld+a+b"
一看就比第一个复杂。答案还写了 merge 函数,还有 for 循环什么的,测试用例看起来并没有这么复杂, so给出自己的答案。
function stringconcat() {
return Array.prototype.slice.call(arguments).join('+')
}
stringconcat.prefix = function (str) {
return function () {
// 这个 str参数挺有意思的
var arr = [str].concat(Array.prototype.slice.call(arguments))
return stringconcat.apply(null, arr)
}
}
看似 stringconcat.prefix()返回的只是一个 function,但实际还是保存了外层传进来的参数形成闭包。
另一个坑就是 return function(){}中,不要忘记把 stringconcat.apply的结果 return 回去,一开始我因为没有加 return 导致折腾了一下午!!!