JS 按顺序打印 0 - 99 或 99 - 0

问题描述

全部。我是 JS 新手。在这里,我遇到了如下所示的 JS 问题:

function print(n) {
    setTimeout(() => {
        console.log(n);
    },Math.floor(Math.random() * 1000));
}
for (var i = 0; i < 100; i++) {
    print(i);
}

要求是:

  1. 您需要更改程序,使其按顺序打印 0-99 或 99-0;
  2. 不能使用全局变量
  3. 只能更改代码内部的setTimeout;
  4. 您不能修改 Math.floor(Math.random() * 1000

在这里我得到了这个问题的一些解决方案,但有些答案我不明白,所以我希望你们能帮助我为什么这可以工作。我理解第一个、第二个和最后一个的答案,但我不太清楚为什么其余的答案可以工作。尤其是第三个,如果我去掉代码return ()=>{}代码仍然有效,但是会报错100Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src <URL> <URL> 'self' 'unsafe-inline' https:".

//1.
function print1(n) {
    setTimeout(() => {
        console.log(n);
    },1,Math.floor(Math.random() * 1000));
}

// 2. 
function print2(n) {
    setTimeout(() => {
        console.log(i--);
    },Math.floor(Math.random() * 1000));
}

// 3.
function print3(n) {
    setTimeout((() => {
        console.log(n)
        return () => { }
    }).call(n,[]),Math.floor(Math.random() * 1000));
}
for (var i = 0; i < 100; i++) {
    print(i);
}

//4.
function print4(n) {

    setTimeout(() => {

        setTimeout(() => {
            console.log(n);
        },1000 * n);

    },Math.floor(Math.random() * 1000));
}

// 5. 
function print5(n) {
    setTimeout((() => {
        console.log(n);
    })(),Math.floor(Math.random() * 1000));
}

解决方法

第三种方法本质上是在 setTimeout 行运行后立即调用函数,在超时回调运行之前。因此,当调用 print(i); 时,在下一次循环开始之前,立即记录该数字。

在功能上,它类似于:

function print3(n) {
    console.log(n);
    setTimeout(<unimporant>);
}

之所以有效,是因为使用 .call 立即调用超时内的函数:

setTimeout((() => {
    console.log(n)
    return () => { }
}).call(n,[]),

简化为

setTimeout((() => {
    console.log(n)
    return () => { }
})(),

基本上就是

console.log(n)
setTimeout((() => {
    return () => { }
})(),

或者,替换从 IIFE 返回的函数:

console.log(n)
setTimeout(() => {},

传递给 setTimeout 的回调没有做任何事情。

如果我去掉代码return()=>{},代码仍然有效,但是会报错

听起来您在最后返回了一个字符串而不是函数,这将导致解释器尝试运行该字符串。虽然在某些环境中可能做这样的事情,但它与eval基本上是一样的。

setTimeout('console.log("never do this");');

这就是警告出现的原因。

,

您可以使用 Array(num) 创建一个长度为 num 的空数组。 然后你可以使用 .fill(n),用 n 填充所有数组索引。 然后,您可以使用 .map() 遍历数组并返回新值以替换我们在 .fill() 中使用的值。

function range(start,end) {
    // checks that the end number is bigger than the start number.
    // this is because it should decrement instead of increment if the end is smaller.
    if(end > start){
        return Array(end - start).fill(0).map((_,i) => start + i)
    } else {
        return Array(start - end).fill(0).map((_,i) => start - i)
    }
}

您可以使用我制作的部分功能来做您想做的事。要打印所有值,只需执行 console.log(...arrayName),或使用 .forEach() 遍历它并打印它们。