如何像在 c 中那样在 JavaScript 中创建一个静态变量? (避免重新初始化变量)

How to make a static variable in JavaScript like we do in c ? ( to avoid re-initialization of the variable)

我在 https://www.youtube.com/watch?v=cjIswDCKgu0&t=429s YouTube 上看过这个视频;

我只是想做一个简单的去抖功能。但是此代码无法按预期在我的设备上运行。请帮忙。


<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="true">
<div class="snippet-code">
<pre><code>let debounceTimes = 0;

// this code does not work as intended
let timeout; // if I make it global it works just fine
// but I don't want to do that for obvious reasons
function debounce(cb, delay = 100) {
  //  let timeout; // this is being reinitialized

  // only if I could do something like this
  // static timeout;
  // to avoid re-initializing the variable
  // return (...args) => {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
    cb();
  }, delay);
  // }
}

window.addEventListener("mousemove", () => {
 // console.log("hello");
 // document.getElementById("debounce").innerText++;
  debounce(
    () => {
      debounceTimes++;
      document.getElementById("debounce").innerText = String(debounceTimes);
  }, 100);
});

在这个例子中,这是不可能的,因为当事件被触发时,它只是运行 debounce 函数,该函数在内部创建变量。要避免 re-initializing 变量,您可以:

  1. 在全局范围内创建变量

  2. 创建另一个函数 returns 去抖功能(因此超时隐藏在函数范围内)

let debounceTimes = 0;

function getDebounce() {
  let timeout;

  function debounce(cb, delay = 100) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      cb();
    }, delay);
  }
  return debounce;
}
const debounce = getDebounce();

window.addEventListener('mousemove', () => {
  debounce(() => {
    debounceTimes++;
    document.getElementById('debounce').innerText = String(debounceTimes);
  }, 100);
});

据我所知,您没有在去抖动函数中使用超时变量,然后尝试将其作为去抖动函数的参数...

let debounceTimes = 0;

// this code does not work as intended
 // if I make it global it works just fine
// but I don't want to do that for obvious reasons
function debounce(timeout, cb, delay = 100) {
  //  let timeout; // this is being reinitialized

  // only if I could do something like this
  // static timeout;
  // to avoid re-initializing the variable
  // return (...args) => {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
    cb();
  }, delay);
  // }
}

window.addEventListener("mousemove", () => {
 // console.log("hello");
 // document.getElementById("debounce").innerText++;
  debounce(
    () => {
      debounceTimes++;
      document.getElementById("debounce").innerText = String(debounceTimes);
  }, 100);
});
 Run code snippetHide resultsExpand snippet

我最终用静态方法和变量制作了一个 class,因为它类似于 C++ 的处理方式。但我更喜欢@Tomasz Staszkiewicz 的回答。他在函数里面又做了一个函数来实现这个。

class ignoreInput {
    static #timeout;
    static debounce (cb, delay = 100) {
        clearTimeout(this.timeout);
        this.timeout = setTimeout(() => {
            cb();
        }
        , delay);
    }

    static throttle (cb, delay = 100) {
        // some code
    }    
};

当你希望一个变量对函数 私有 但超出其范围时,JS 中的一个好模式是使用 closuresIIFE:

const debounce = (function() {
  let debounceTimes = 0;
  let timeout; // if I make it global it works just fine
  // but I don't want to do that for obvious reasons
  return (cb, delay = 100) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      cb();
      console.log("Count:", debounceTimes)
      debounceTimes++
    }, delay);
  }
})()

window.onmousemove = () => debounce(() => console.log("Debounced"),200)