MDN 上的说明 "Use functions instead of evaluating snippets of code" - 为什么?

Clarifications on MDN "Use functions instead of evaluating snippets of code" - why's that?

在关于 eval 的 MDN 文章中有一个标题为 Use functions instead of evaluating snippets of code 的段落,在示例代码中有一个关于 setTimeout() 的参考。我不明白为什么这个 advice/command,所以,保留 setTimeout() 参考,有人能指出我为什么这些代码按预期工作吗:

function timedPromise(){
  return new Promise((resolve) => {
    setTimeout(( ) => {resolve(console.log('Promise resolved!'))}, 1000)
  })
};
 
function timedPromise2(){
  return new Promise((resolve) => {
    setTimeout(function(){resolve(console.log('Another promise resolved!'))}, 2000)
  })
};
timedPromise();
timedPromise2();
/*output:
Promise {<pending>}
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined
Promise resolved! //after at least 1s
Another promise resolved! //after at least 2s
*/

虽然这段代码不会?

function timedPromise(){
  return new Promise((resolve) => {
    setTimeout(resolve(console.log('I resolved!')), 1000)
  })
};
 
timedPromise();
/*output:
I resolved! //immediate
Promise {<fulfilled>: undefined}
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined
*/

我理解浏览器将代码片段评估为string而不是函数,然后立即解释并执行它,而不是等待 setTimeout() 的延迟过去。

为什么?

Why/when 我应该使用包装函数而不是代码片段作为参数吗?是不是只和异步有关的东西?

当你写functionName()时,()会立即调用该函数。

所以当你写 setTimeout(resolve(console.log('I resolved!')), 1000) 时:

  • 首先调用 console.log 将其 return 值传递给 resolve;
  • 调用 resolve 将其值传递给 setTimeout;
  • 通话 setTimeout

当您将函数包装在 lambda 中时,您是在将 reference 传递给该函数,而不是立即调用它。这样看可能更清楚:

function doLog() { console.log("Hello, world!"); }

// Calls doLog instantly, passes in return value of undefined
setTimeout(doLog(), 1000); 

// Passes in a reference to doLog, which setTimeout will then call later
setTimeout(doLog, 1000);