Почему моя функция не вызывается в моем SetInterval?

Я впервые использую классы JS. У меня есть setInterval в функции, но функция, которая должна повторяться, но я не уверен, почему это не так.

    class Stopwatch 
    {
    constructor(isRunning, timer, timerTime)
    {
        this.isRunning = isRunning;
        this.timer = timer;
        this.timerTime = timerTime; 
    }
    init()
    {
    // Put the element on the page with an id of start in a variable
    // Do the same for the stop button and the reset button
    const startButton = document.getElementById("start");
    const stopButton = document.getElementById("stop");
    const resetButton = document.getElementById("reset");


    // Add an onclick handler to each of the buttons
    // Use the functions startTimer, stopTimer and resetTimer 
    startButton.onclick = this.startTimer;
    stopButton.onclick = this.stopTimer;
    resetButton.onclick = this.resetTimer;
    }
    startTimer() 
    {
        // if the timer is NOT running, start it
        // call the function incrementTimer every second
        // save the timer in a the timer variable

        if (!this.isRunning)
        {
            this.isRunning = true;
            this.timer = setInterval(this.incrementTimer, 1000);

        }
    }

    incrementTimer() 
    {
        // increment the timerTime
        // calculate the number of minutes and seconds
        this.timerTime++;
        let minutes = Math.floor(this.timerTime / 60);
        let seconds = this.timerTime % 60;
        // write the minutes and seconds to the elements on the page
        // use the function pad to make sure there's a leading 0 if necessary
        document.getElementById("minutes").innerHTML = this.pad(this.minutes);
        document.getElementById("seconds").innerHTML = this.pad(this.seconds);

    }

    pad(number) 
    {
        // add a leading 0 if the number is < 10
        if (number < 10)
            number = "0" + number;

        return number;
    }

    stopTimer() 
    {
        // if the timer is running, stop it
        if (this.isRunning)
        {
            isRunning = false;
            timer = clearInterval(timer);
        }

    }

    resetTimer() 
    {
        // stop the timer
        this.stopTimer();

        // set the timerTime back to 0
        this.timerTime = 0;

        // write 00 to the elements on the page for minutes and seconds
        document.getElementById("minutes").innerHTML = "00";
        document.getElementById("seconds").innerHTML = "00";
    }
}



let stopwatch = new Stopwatch(false, null, 0);

// When the page has finished loading, call the function init
window.onload = stopwatch.init();

isRunning является ложным

Patrick Behrens 09.04.2019 01:36
this.isRunning и isRunning — это не одно и то же, как и timer в StopTimer.
charlietfl 09.04.2019 01:40
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Когда вы устанавливаете свойство onclick элемента, назначаемая вами функция всегда будет вызываться со значением this, установленным для элемента. Таким образом, свойства this, к которым вы пытаетесь получить доступ, не будут определены.

Вместо:

startButton.onclick = this.startTimer;

Используйте Function.prototype.bind, чтобы установить значение this, с которым будет вызываться функция:

startButton.onclick = this.startTimer.bind(this);

Кроме того, ваш код для увеличения таймера неверен:

let minutes = Math.floor(this.timerTime / 60);
let seconds = this.timerTime % 60;
document.getElementById("minutes").innerHTML = this.pad(this.minutes);
document.getElementById("seconds").innerHTML = this.pad(this.seconds);

this.minutes не определено, поскольку вы использовали let для объявления минут и секунд. Вместо этого просто ссылайтесь на переменные, используя их имена, то есть minutes и seconds.

document.getElementById("minutes").innerHTML = this.pad(minutes);
document.getElementById("seconds").innerHTML = this.pad(seconds);

Когда вы останавливаете таймер, вы забыли добавить this перед свойством, к которому пытались получить доступ.

Этот:

if (this.isRunning){
    isRunning = false;//isRunning is not defined as a local or global variables
    timer = clearInterval(timer);//timer is not defined
}

Должно быть:

if (this.isRunning){
  this.isRunning = false;
  this.timer = clearInterval(this.timer);
} 

Демо:

<button id = "start">
Start
</button>
<button id = "stop">
Stop
</button>
<button id = "reset">
Reset
</button>
<span id = "minutes"></span>:<span id = "seconds"></span>
<script>
    class Stopwatch 
    {
    constructor(isRunning, timer, timerTime)
    {
        this.isRunning = isRunning;
        this.timer = timer;
        this.timerTime = timerTime; 
    }
    init()
    {
    // Put the element on the page with an id of start in a variable
    // Do the same for the stop button and the reset button
    const startButton = document.getElementById("start");
    const stopButton = document.getElementById("stop");
    const resetButton = document.getElementById("reset");


    // Add an onclick handler to each of the buttons
    // Use the functions startTimer, stopTimer and resetTimer 
    startButton.onclick = this.startTimer.bind(this);
    stopButton.onclick = this.stopTimer.bind(this);
    resetButton.onclick = this.resetTimer.bind(this);
    }
    startTimer() 
    {
        // if the timer is NOT running, start it
        // call the function incrementTimer every second
        // save the timer in a the timer variable
        if (!this.isRunning)
        {
            this.isRunning = true;
            this.timer = setInterval(this.incrementTimer.bind(this), 1000);
        }
    }

    incrementTimer() 
    {
        // increment the timerTime
        // calculate the number of minutes and seconds
        this.timerTime++;
        let minutes = Math.floor(this.timerTime / 60);
        let seconds = this.timerTime % 60;
        // write the minutes and seconds to the elements on the page
        // use the function pad to make sure there's a leading 0 if necessary
        document.getElementById("minutes").innerHTML = this.pad(minutes);
        document.getElementById("seconds").innerHTML = this.pad(seconds);

    }

    pad(number) 
    {
        // add a leading 0 if the number is < 10
        if (number < 10)
            number = "0" + number;

        return number;
    }

    stopTimer() 
    {
        // if the timer is running, stop it
        if (this.isRunning)
        {
            this.isRunning = false;
            this.timer = clearInterval(this.timer);
        }

    }

    resetTimer() 
    {
        // stop the timer
        this.stopTimer();

        // set the timerTime back to 0
        this.timerTime = 0;

        // write 00 to the elements on the page for minutes and seconds
        document.getElementById("minutes").innerHTML = "00";
        document.getElementById("seconds").innerHTML = "00";
    }
}



let stopwatch = new Stopwatch(false, null, 0);

// When the page has finished loading, call the function init
window.onload = stopwatch.init();
</script>

Другие вопросы по теме