Javascript 为什么for循环中setTimeout内的IIFE在NodeJ中的行为与浏览器中的行为不同

Javascript 为什么for循环中setTimeout内的IIFE在NodeJ中的行为与浏览器中的行为不同,javascript,node.js,Javascript,Node.js,当我使用setTimeout执行一个简单的for循环时,我发现这很有趣,它在我的浏览器中运行良好,但在节点环境中不工作 我的代码是 function run(times) { for (var i = 0; i < times; i++) { setTimeout((function(j) { console.log(j); })(i), i * 10 ); } } run(7); 函数运行(次){ 对于(变量i=0;i

当我使用setTimeout执行一个简单的for循环时,我发现这很有趣,它在我的浏览器中运行良好,但在节点环境中不工作

我的代码是

function run(times) {
 for (var i = 0; i < times; i++) {
   setTimeout((function(j) {
     console.log(j);
   })(i), i * 10 );
 }
}

run(7);
函数运行(次){
对于(变量i=0;i<次;i++){
setTimeout((函数(j){
控制台日志(j);
})(i) ,i*10);
}
}
运行(7);
虽然这段代码在浏览器中运行良好,但在节点环境中不起作用。我出错了

timers.js:327
throw new TypeError('"callback" argument must be a function');
^

TypeError: "callback" argument must be a function
at exports.setTimeout (timers.js:327:11)
at countWithSetTimeout (E:\eckovation\temp\demo.js:3:8)
at Object.<anonymous> (E:\eckovation\temp\demo.js:9:1)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:394:7)
timers.js:327
抛出新的TypeError(“'callback'参数必须是函数”);
^
TypeError:“回调”参数必须是函数
at exports.setTimeout(timers.js:327:11)
在countWithSetTimeout(E:\eckovation\temp\demo.js:3:8)
反对。(E:\eckovation\temp\demo.js:9:1)
在模块处编译(Module.js:570:32)
在Object.Module.\u extensions..js(Module.js:579:10)
在Module.load(Module.js:487:32)
在tryModuleLoad时(module.js:446:12)
在Function.Module.\u加载(Module.js:438:3)
位于Module.runMain(Module.js:604:10)
运行时(bootstrap_node.js:394:7)

有人能解释为什么会发生这种情况吗?

节点正确地识别出您没有在
setTimeout
中传递函数。IIFE的返回值为
未定义

这里唯一的区别似乎是浏览器将安静地容忍
setTimeout(未定义,n)
,而节点不会


如果要将函数传递给
setTimeout
,实际上必须
从生活中返回
function

您不是在第一个参数中传递函数,而是在传递立即调用的函数的结果。在这种特殊情况下,函数没有显式的
返回
,因此默认返回值为
未定义
,这不是函数

假设您试图使用闭包捕获当前循环迭代值,您也可以使用
let
声明,该声明的作用域为
for
块,例如:

function run(times) {
  for (let i = 0; i < times; i++) {
    setTimeout(function() {
      console.log(i);
    }, i * 10 );
  }
}
函数运行(次){
for(设i=0;i
setTimeout
需要回调作为第一个参数,在您的代码中,浏览器忽略了这一点,只是在循环内执行函数并显示它,尝试增加时间(第二个参数是
setTimeout
),即使在浏览器上也不会有任何效果,函数将立即执行。
正如other node.js所提到的,正确地识别并抛出一个错误。

您没有将函数传递给
setTimeout
。在浏览器中,代码发生得如此之快,以至于它看起来正在工作,但实际上它是以迭代的方式进行的。