【问题标题】:setTimeout function parameters undefined (JS) [duplicate]setTimeout 函数参数未定义(JS)[重复]
【发布时间】:2020-05-08 18:45:08
【问题描述】:

我一直找不到合适的解释。

function subtract(x, y) {
    setTimeout(function(x, y) {
      document.write(x - y);
  }, 1000);
}

subtract(1, 1);

这会将 NaN 写入文档,因为传递给 setTimeout 的 x 和 y 参数未定义。你会认为 x 和 y 应该是整数 1 并且它在减法函数的范围内。以下 sn-p 工作得非常好,并按预期写入整数 0:

function subtract(x, y) {
    setTimeout(function() {
      document.write(x - y);
  }, 1000);
}

subtract(1, 1);

删除参数似乎可以解决问题。为什么?

【问题讨论】:

标签: javascript settimeout


【解决方案1】:

你还没有将参数传递给函数回调,当回调最终被setTimeout调用时,xyundefined

所以您看到NaN 作为输出,因为undefined - undefinedNaN

setTimeout 采用您在delay 参数之后传递的函数回调的参数,在您的情况下是在1000 之后。

在不传递参数的情况下,xy 变量的作用域为函数回调。它不会从外部范围获取值,因为它被您提供的函数参数所遮蔽。

function subtract(x, y) {
    setTimeout(function(x, y) {
      document.write(x - y);
  }, 1000, 1, 1);
}

subtract(1, 1);

您也可以使用Function.prototype.bind 将参数传递给回调函数。

bindthis 上下文作为第一个参数,其余参数是函数的参数。在我的示例中,我将 null 作为 this 上下文:

function subtract(x, y) {
    setTimeout(function(x, y) {
      document.write(x - y);
  }.bind(null,1,1), 500);
}

subtract(1, 1);

【讨论】:

  • 这应该可以,但是 IE9 和更早的版本(我知道,真的很旧)不会将额外的参数传递给回调。
【解决方案2】:

这是一个 javascript 参考问题 https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout

在 -- “this”问题部分他们提到了同样的问题

【讨论】:

    【解决方案3】:

    这是因为闭包、异步函数和执行上下文。 settimeout 是异步函数,意味着它不会等待或阻止执行。 Settimeout 函数由 eventloop tick 执行。 当您不将参数传递给其中的函数时,它将包含来自减法函数的值并将其存储以在执行时使用。这是因为闭包的概念。 如果我们传递参数,它就不再像闭包一样,并且在执行时期望参数为空。所以你得到NaN。 对于实验,在 settimeout 中将默认参数传递给函数并检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-24
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 2018-09-14
      相关资源
      最近更新 更多