欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

js之一个有意思的逻辑题

程序员文章站 2022-03-12 16:55:09
...

js之一个有意思的逻辑题

昨天偶然看见一个技术群里面在讨论一道js的逻辑题,很快就有人给出答案来了,但是我却想了半天,这里之所以记载,不是单纯的记录一种答案,而是多种,废话不多说,直接上题目

定义一个函数,比如:var repeatFun = repeat(alert, 10, 3000),调用repeatFun(‘hellword’),会alert10次helloworld,每次间隔3s

看到这个题目,怎么样,你是直接出答案吗?好吧,趁着还没忘记,我这里先记录一下我开始写这道题的感受吧,首先呢,看到这道题,前面半句我没看懂,我知道它想让我lert10次helloWord,每次间隔3s,这是我读题所知道的需求。但是我的神一样的理解竟然变成了这样:(哦,这是要我每间隔三秒alert10次HelloWord,好吧,然后这就是我的神逻辑,一直陷入死循环出不来,js之一个有意思的逻辑题
好了不开玩笑了,还是言归正传的记录答案。

首先呢,一位对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');

没错,这是我上面那段代码的一点点小改变,但是结果却是不同的哦。