setTimeout不适用于中等负数

jca*_*er2 4 javascript settimeout

如果setTimeout使用较小或较大的负数进行呼叫,则会立即运行回调,但如果使用中等负数,则回调永远不会运行.有人可以解释一下吗?

// Y and Z are printed, but not X

var x = -7677576503;
var y = -1000000000;
var z = -10000000000;

setTimeout(function () {
  console.log('x');
}, x);
setTimeout(function () {
  console.log('y');
}, y);
setTimeout(function () {
  console.log('z');
}, z);
Run Code Online (Sandbox Code Playgroud)

JSFiddle版本

(在Chromium 57.0.2987.98和Firefox 50.1.0上测试)

rle*_*mon 12

我想我有答案.
根据MDN:

包括Internet Explorer,Chrome,Safari和Firefox在内的浏览器将延迟存储为内部的32位有符号整数.

浏览器将此值转换为32位signed int.因此,当它看到你传递的值时,我们可以假设它实际上是作用于它转换为该类型的值,ECMAScript规范说逐位运算的返回值必须是32位int.

运行时语义:评估生产A:A @ B,其中@是上述产品中的一个按位运算符,评估如下:
... [snipped].
返回将按位运算符@应用于lnum和rnum的结果.结果是带符号的32位整数.

所以,如果我们将它们放在一起并测试你给出的值:

x | 0 === 912358089,所以超时最终将被执行..只是在一段时间.
y | 0 === -1000000000,并立即触发回调*.
z | 0 === -1410065408,仍然是负面的,仍然立即被解雇*.

*所有测试都以chrome最新稳定完成

您可以使用其他负数进行测试,这些负数在转换为32位有符号整数时会产生正数.
-7000000000 | 0会导致1589934592,并且呼叫setTimeout(fn, -7000000000)似乎没有......今天.

请记住,这是我对正在发生的事情的最好猜测.祝好运!

编辑:感谢Vivek Athalye,我想我已经确认这是发生了什么.

-4294967290000 | 0 === 6000,如果你setTimeout(_ => console.log(1), -4294967290000)在aprox中运行那场大火.6秒

  • "这是我最好的猜测:猜猜?它很合乎逻辑...... +1 (2认同)
  • 怎么样:`-4294967295 | 0`应该给1 (2认同)
  • 哇,那实际上超级有用.`-4294967290000 | 0`是6000,并且在~6秒后响应.我认为这是一个坚实的证实. (2认同)