我的 JavaScript 时钟小部件使 Firefox 崩溃

My JavaScript clock widget crashes Firefox

我是一个 JavaScript 菜鸟,我意识到我需要帮助。

我只想在单独的 SPAN 中显示一个带有时间和 AM/PM 的简单实时时钟。

问题是,如果我将选项卡打开 20-40 分钟(根据我打开的其他选项卡的数量而有所不同),它会导致选项卡崩溃并出现内存不足错误。我目前只在 Firefox (72.0.2) 上测试过。

为什么我的代码占用大量内存?它通常从 2.4MB 左右开始,然后逐渐增加并超过 42MB,然后再次下降,再次增加并重复循环几次,直到选项卡崩溃。

我读过关于垃圾收集的资料,但不知道它是如何工作的,也不知道它是否与这个问题有关。

请注意,我已尝试将 setInterval 与 setTimeout 交换,但结果相同。

这是我的 JavaScript:

window.onload = function() {
  clock();

  function clock() {
    var now = new Date();
    var TwentyFourHour = now.getHours();
    var hour = now.getHours();
    var min = now.getMinutes();
    var sec = now.getSeconds();
    var mid = 'PM';

    if (min < 10) {
      min = "0" + min;
    }
    if (hour > 12) {
      hour = hour - 12;
    }
    if (hour == 0) {
      hour = 12;
    }
    if (TwentyFourHour < 12) {
      mid = 'AM';
    }

    document.getElementById('time-core').innerHTML = hour + ':' + min;
    setInterval(clock, 1000);
    document.getElementById('time-suffix').innerHTML = mid;
    setInterval(clock, 1000);
  }
}

这是我的 HTML:

<span class="show-time" id="time-core"></span><span class="show-time-suffix" id="time-suffix"></span>

谢谢!

正如 Andreas 在他的评论中所说:

Every call of clock() adds two new intervals that each will call clock(). So after the first round we then have two scheduled clock() calls, then 4, then 8, then ...

解决这个问题的一种方法是从 clock 函数中删除 setInterval,如下例所示。

window.onload = function() {
  clock(); // Run it first so we don't have to wait 1 second
  setInterval(clock, 1000); // Updates the clock every second

  function clock() {
    var now = new Date();
    var TwentyFourHour = now.getHours();
    var hour = now.getHours();
    var min = now.getMinutes();
    var sec = now.getSeconds();
    var mid = 'PM';

    if (min < 10) {
      min = "0" + min;
    }
    if (hour > 12) {
      hour = hour - 12;
    }
    if (hour == 0) {
      hour = 12;
    }
    if (TwentyFourHour < 12) {
      mid = 'AM';
    }

    document.getElementById('time-core').innerHTML = hour + ':' + min;
    document.getElementById('time-suffix').innerHTML = mid;
  }
}