【问题标题】:I can't call a class function inside another class function in Javascript我不能在 Javascript 中的另一个类函数中调用一个类函数
【发布时间】:2022-01-14 01:07:22
【问题描述】:

我想在“startTimer”中调用函数“displayTime”,但由于某种原因,我在控制台中收到“Uncaught TypeError: this.displayTime is not a function”。

let endTimer = "0";
let isRunning = false;

//! CLASS
class Timer {
  constructor(endTimer, isRunning) {
    this.endTimer = endTimer;
    this.isRunning = isRunning;
  }

  startTimer() {
    if (this.endTimer === "0") {
      this.endTimer = new Date().getTime() + 1500000;
    }
    displayTime();
    if (this.isRunning === true) {
      this.pauseTimer();
      this.isRunning
    }
    this.isRunning = true;
  }

  displayTime() {
    let now = new Date().getTime();
    let remainingTime = this.endTimer - now;
    let minutes = Math.floor(remainingTime / 1000 / 60);
    let seconds = Math.floor((remainingTime / 1000) % 60);
    if (seconds < 10) {
      seconds = "0" + seconds;
    }
    timer.innerHTML = `<h1>${minutes}:${seconds}</h1>`;
    start.textContent = "STOP"
    this.update = setInterval(this.displayTime, 100);
  }
}

let newTimer = new Timer(endTimer, isRunning);

//! EVENT LISTENERS

start.addEventListener("click", newTimer.startTimer);

我认为我遗漏了一些明显的东西,但我不明白什么......

【问题讨论】:

标签: javascript class


【解决方案1】:
start.addEventListener("click", newTimer.startTimer.bind(newTimer));

【讨论】:

  • 谢谢,成功了!现在的问题是,如果我再次单击相同的按钮,将不会调用相同的函数。它是 .bind() 的副作用吗?我怎样才能再次调用该函数?
  • 没关系,我解决了这个问题,谢谢!
【解决方案2】:

调用 displayTime();正如上面 cmets 中的 GenericUserHeretic Monkey 所提到的,没有前置关键字“this”是主要问题(下面的第 16 行)。

您可能已经知道这一点,但您也想定义一个 pauseTimer() 方法/函数。

let endTimer = "0";
let isRunning = false;

//! CLASS
class Timer {
constructor(endTimer, isRunning) {
    this.endTimer = endTimer;
    this.isRunning = isRunning;
  }
}

Timer.prototype.startTimer = function() {
    if (this.endTimer === "0") {
        this.endTimer = new Date().getTime() + 1500000;
    }
    this.displayTime(); // this is the important line
    if (this.isRunning === true) {
        this.pauseTimer();
        this.isRunning
    }
    this.isRunning = true;
}

Timer.prototype.displayTime = function() {
    let now = new Date().getTime();
    let remainingTime = this.endTimer - now;
    let minutes = Math.floor(remainingTime / 1000 / 60);
    let seconds = Math.floor((remainingTime / 1000) % 60);
    if (seconds < 10) {
    seconds = "0" + seconds;
    }
    //timer.innerHTML = `<h1>${minutes}:${seconds}</h1>`;
    //start.textContent = "STOP"
    this.update = setInterval(this.displayTime, 100);
}

Timer.prototype.pauseTimer = function() {
    this.isRunning = false;
}

let newTimer = new Timer("0", true);
newTimer.startTimer();

//! EVENT LISTENERS

//start.addEventListener("click", newTimer.startTimer);

【讨论】:

  • 我实际上把上传的代码搞砸了,我调用的确实是“this.displayTimer”,所以问题不在于这个。这是我从其他 cmets 看到的事件侦听器的问题:start.addEventListener("click", () =&gt; { newTimer.startTimer(); }) 这工作正常并正确调用 startTimer,与方法 .bind() 相同。现在的问题是,我似乎无法再次单击“开始”按钮,只是由于某种原因没有注册单击。也许是因为对象不再相同了?我真的不知道
  • 没关系,我解决了,谢谢!
【解决方案3】:
class Timer {
    startTimer() {
        // You forgot this keyword
        this.displayTime();
    }
    displayTime() {
        console.log('do something');
    }

}

let newTimer = new Timer();

// addEventListener changes the context of this.
// Using an arrow function will keep 'this' keyword in tact inside startTimer method 
start.addEventListener('click', () => newTimer.startTimer)

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-10
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多