js之一个有意思的逻辑题
js之一个有意思的逻辑题
昨天偶然看见一个技术群里面在讨论一道js的逻辑题,很快就有人给出答案来了,但是我却想了半天,这里之所以记载,不是单纯的记录一种答案,而是多种,废话不多说,直接上题目
定义一个函数,比如:var repeatFun = repeat(alert, 10, 3000),调用repeatFun(‘hellword’),会alert10次helloworld,每次间隔3s
看到这个题目,怎么样,你是直接出答案吗?好吧,趁着还没忘记,我这里先记录一下我开始写这道题的感受吧,首先呢,看到这道题,前面半句我没看懂,我知道它想让我lert10次helloWord,每次间隔3s,这是我读题所知道的需求。但是我的神一样的理解竟然变成了这样:(哦,这是要我每间隔三秒alert10次HelloWord,好吧,然后这就是我的神逻辑,一直陷入死循环出不来,)
好了不开玩笑了,还是言归正传的记录答案。
首先呢,一位对es6语法很熟悉的大佬很快速的给出了答案,然后获得了无数点赞,让我们来看看神一样的答案吧!
es6解题思路:
((str)=>{
let count = 0;
let fn = ()=>{
console.log(str+count);
count++;
if(count<10) setTimeout(fn,3000)
}
fn()
})('hellword')
怎么样是不是很快,但是好吧,也许你会说,我还没有掌握es6语法呀,或者你想说,我们的项目里面还没有用到es6语法呀,怎么办呢。好吧,没多大事,因为我就是没有太掌握es6的语法,但是好在我能看懂es6,所以我将它翻译成es5写法了。下面就来看看翻译后的答案吧!
es5解题思路:
function test(aa) {
var i=0;
function test02() {
console.log(aa+i);
i++;
if(i<10) setTimeout(test02,3000)
}
test02();
}
test('helloword');
好了,看到这里,本来以为,嗯差不多了,就是这样,但是后来大佬又来了一种方法,我个人觉得很简单明了,是什么呢,你猜到了吗,好吧,直接说吧,就是递归。如果暂时不给答案,你是否能用递归的思想做出来呢。好了这里直接出答案吧!
递归解题思路:
const repeat = (msg, count) => {
setTimeout(() => {
console.log(msg);
count < 9 && repeat(msg, count + 1)
}, 3000);
}
repeat('helloword',0)
下面给它翻译成普通写法:
function rr(ww,i) {
setTimeout(function () {
console.log(ww+i);
if(i<9){
rr(ww,i+1);
}
},1000)
}
rr('helloword',0);
还有一种方法,就是用到for循环,先看一下,我用for循环写的答案吧!
用for循环解题思路:
function test(qq,count,e) {
for(var i=0;i<count;i++){
test02(qq,i,e);
}
}
function test02(a,bcount,c) {
setTimeout(function () {
console.log(a+bcount);
},bcount*c)
}
test('helloword',10,3000);
ok,看完上面这个,我搜集到了一个大佬的另外一种解法,他给他取了一个名字,柯里化解法,好,下面直接上代码吧!如果有不懂柯里化是啥意思的小伙伴,这里提供一个链接解释吧!http://www.ruanyifeng.com/blog/2017/02/fp-tutorial.html
柯里化解法:
function repeat(alert, count, duration) {
return text => {
for (let i = 0; i < count; i++) {
setTimeout(() => {
alert(text)
},duration * i)
}
}
}
var repeatFun = repeat(alert, 3, 3000)
repeatFun('hellword')
上面是大佬的源代码,未经改动,下面为了不懂es6的朋友着想,也为了自己更好理解,我给他翻译成普通函数的写法。
柯里化普通函数写法:
function test(count,dur) {
return function test02 (text) {
for(let i=0;i<count;i++){
setTimeout(function () {
console.log(text+i);
},dur * i)
}
}
}
test(10,3000)('helloword');
好了一个题目引发出来了很多知识点,感觉还是比较有意思的,这里不多说了,感兴趣的朋友还是去了解一下柯里化吧。另外结尾了丢一段代码出来,思考一下两者结果为何不同吧!
function test(count,dur) {
return function test02 (text) {
for(var i=0;i<count;i++){
setTimeout(function () {
console.log(text+i);
},dur * i)
}
}
}
test(10,3000)('helloword');
没错,这是我上面那段代码的一点点小改变,但是结果却是不同的哦。