重新分配超时变量如何影响 Settimeout

How does reassigning the timeout variable impact Settimeout

考虑一下:

var x = null;

function a() {
  x = window.setTimeout(() => {
    alert("hello")
  })
}

a();

function b() {
  window.clearTimeout(x);
  alert("bye")
}

b();

上面的代码片段只会打印 bye 而不会打印 hello。但是,如果我只是在方法 b 中重新分配 x,hellobye 都会被打印出来。机制是什么?

var x = null;

function a() {
  x = window.setTimeout(() => {
    alert("hello")
  })
}

a();

function b() {
  x = undefined;
  window.clearTimeout(x);
  alert("bye")
}

b();

"timeout variable"只是一个数字,超时的ID。重新分配数字分配给的变量本身不是问题,但如果您想清除超时,则必须将相同的超时 ID 传递给 clearTimeout。只是为了说明,并不是说你应该在实际代码中这样做,你可以在页面加载开始时调用 setTimeout 并获得超时 ID 1,然后用 1 调用 clearTimeout,然后超时将被清除:

x = window.setTimeout(() => {
  alert("hello")
});
window.clearTimeout(1);

变量本身没什么特别的,它只是 ,您需要跟踪的数字,以便将其传递给 clearTimeout

在您的第二个代码段中,因为您在执行 clearTimeout(x) 之前将 undefined 分配给 x,解释器不知道 ID 为 [=] 的持续超时17=],所以它没有清除任何东西。

您也可以将超时 ID 号分配给一个 不同的 变量,并清除原始变量:

var x = null;

function a() {

  x = window.setTimeout(() => {
    alert("hello")
  })
}
a();

function b() {
  const savedX = x;
  x = undefined;
  window.clearTimeout(savedX);
  alert("bye")
}
b();

这是因为 window.clearTimeout(x); 先调用并清除超时,这就是为什么没有 hello 警报。

如果你使用 setTimeout 没有延迟参数,它会执行下一个事件周期,这意味着在你的情况下 b() 执行之后。

在第二种情况下,您将 x 重新分配给 undefined,因此 x 不再指向相同的 setTiemout ID。因此 window.clearTimeout(x) 不会清除超时。

From MDN docs

delay

The time, in milliseconds (thousandths of a second), the timer should wait before the specified function or code is executed. If this argument is omitted, a value of 0 is used, meaning execute "immediately", or more accurately, the next event cycle. Note that in either case, the actual delay may be longer than intended;