在 javascript class 中调用 class 方法

Calling class methods inside javascript class

这是一个 Vue class。方法 signOut() 应该在计时器滴答时触发。定时器工作,除了调用 signOut().

问题在于访问 class 方法。我对 this、self 和访问修饰符感到困惑。 我试过 this.signOut() 但它不起作用。

如何调用方法 signOut

"use strict";

(async (globals, config, loader, application) => {

    const storageLocal = await loader.services.storage.local.getAsync();

    class HeaderComponent {
        #foo = a;

        constructor(tag) {
            this.tag = tag;

            this.timer();
        }

        signOut() {
            storageLocal.delete('account');
            window.location = '/signin.html';
        }

        timer() {
            //document.getElementById("timer"), 
            var counter = -1;
            var timeout;
            var startTimer = function timer() {
                counter++;
                console.log(counter);

                signOut(); //<- error can't call class method
                timeout = setTimeout(timer, 10000);
            };

            function resetTimer() {
                // here you reset the timer...
                clearTimeout(timeout);
                counter = -1;
                startTimer();
                //... and also you could start again some other action
            }

            document.addEventListener("mousemove", resetTimer);
            document.addEventListener("keypress", resetTimer);
            startTimer();
        }

        data() {
            return { account: storageLocal.account };
        }
    }

    const component = new HeaderComponent('component-header')
    loader.components.set(component.tag, component);

})(window, window.config, window.loader, window.application);

请注意:

        signOut() {
            storageLocal.delete('account');
            window.location = '/signin.html';
        }

        timer() {
            //document.getElementById("timer"), 
            var counter = -1;
            var timeout;
            var startTimer = function timer() {

如您所见,'signOut()' 比活动功能低 2 级。逻辑说它会像 this.parent.signOut() 一样工作,但它不会!

EDIT3:this.signOut(); 将产生

Uncaught TypeError: Cannot read property 'signOut' of undefined
    at timer (header.js:30)
    at HTMLDocument.resetTimer

您需要 this 并称其为 this.signOut()

function 创建了一个新的上下文。您需要切换到箭头功能并使用 this.signOut()。简化示例:

  timer() {
    var counter = -1;
    var timeout;
    var startTimer = () => {
      counter++;
      console.log(counter);

      this.signOut();
      timeout = setTimeout(startTimer, 1000);
    };

    setTimeout(startTimer, 1000);
  }

此外,您在一个 class 中定义了两个 signOut() 方法。

startTimer-函数在 HeaderComponent 实例的上下文中不 运行。 startTimer 中的 thissetTimeout 中作为处理程序执行时将指向 window

为了访问 HeaderComponent 的实例,要么使用箭头函数(如先前答案中指出的那样。另请参阅 Arrow function expressions),它将指向 this外部上下文(即 HeaderComponent 的实例)或在 timer 中定义指向实例的标识符(例如 const self = this;)并使用 self 而不是 thisstartTimer.

将此应用于您的示例(为了保持一致性,我使用 var 而不是 const):

        timer() {
            var counter = -1;
            var timeout;
            var self = this;
            var startTimer = function() { // Don't use a named function here, it only leads to more confusion
                counter++;
                console.log(counter);

                self.signOut(); // Use `this` of the outer context
                timeout = setTimeout(startTimer, 10000);  // Use the declared identifier
            };

            // Rest of the method
        }

this is Javascript 对于来自不同编程语言的人来说可能有点混乱。如果您想了解更多细节,我建议您阅读 MDN reference for this and into Closures