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

JS print 0 - 99 or 99 - 0 in order

全部。我是 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 行 运行s, 超时回调 运行s 之前立即调用一个函数。因此,当调用 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 的回调没有做任何事情。

if I remove the code return ()=>{}, the code still works but it will report an error

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

相同。

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

这就是出现警告的原因。

您可以使用 Array(num) 来创建一个长度为 num 的空数组。 然后你可以使用 .fill(n),用 n 填充所有数组索引。 然后你可以使用 .map() 遍历数组和 return 新值来替换我们在 .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() 遍历它并打印它们。