Как сохранить переменную внутренней области видимости для использования с внешней областью видимости? - PullRequest
0 голосов
/ 24 июня 2019

Как получить переменную cool, чтобы я мог использовать ее вне функции gotSpeech()? Я хочу использовать его для функции guessedCorrect(), которая также будет запускаться при нажатии на кнопку. Это возможно?

let speechRec = new p5.SpeechRec('en-US', gotSpeech);

function gotSpeech() {
    if (speechRec.resultValue) {
        cool = speechRec.resultString;
        if (cool == "0") {
            zero.style.color = "#dc3545";
        }
        if (cool == "5") {
            five.style.color = "#dc3545";
        }
        if (cool == "10") {
            ten.style.color = "#dc3545";
        }
        if (cool == "15") {
            fifteen.style.color = "#dc3545";
        }
        if (cool == "20") {
            twenty.style.color = "#dc3545";
        }
    }
}

button.addEventListener("click", function(event) {
    resetround();
    speechRec.start();
    setTimeout("getComputerChoice()", 3000);
    setTimeout("identifyHands()", 3000);
    clearInterval(myInterval);
    myInterval = setInterval(function() {
        time--;
        if (time == -1) {
            button.innerHTML = "Again";
            clearInterval(myInterval);
            time = 4;
        } else {
            button.innerHTML = "Start";
            numbers.innerHTML = time;
        }
    }, 1000);
    setTimeout("guessedCorrect()", 5000);
})

Вывод возвращает undefined, когда он находится за пределами области видимости.

Ответы [ 2 ]

2 голосов
/ 24 июня 2019

Есть несколько способов сделать это. Наиболее очевидным является изменение вашего вызова на guessedCorrect(), чтобы явно передать его:

setTimeout(() => { guessedCorrect(cool); }, 5000);

Конечно, это будет означать, что вам нужно будет изменить определение guessedCorrect(), чтобы приспособить входящий аргумент, т. Е .:

function guessedCorrect(cool) { //...

Это имеет преимущество в том, что не ссылается на функцию по имени строки. Как говорит @Shahzad, это приведет к поломке вашего кода при минификации, так как минификация не меняет строк. Лучше использовать ссылки на функции, поэтому:

setTimeout(guessedCorrect, 5000);

Кроме того, ваш повторяющийся блог if/else if может быть значительно уменьшен при использовании блока switch() или даже объекта в качестве карты значений в цветах.

[EDIT]

В ответ на ваш более поздний комментарий:

this - это контекст, в котором выполняется текущее закрытие. Контекст по умолчанию, то есть до тех пор, пока что-то его не изменит, - window. Часто контекст устанавливается автоматически, например, в обратных вызовах событий, где this указывает на инициирующий элемент. Но в вашем случае мы могли бы (хотя это был бы довольно странный подход) придумать this, чтобы указать на значение cool, поэтому:

setTimeout(guessedCorrect.bind(cool), 5000);

После этого вызов this внутри guessedCorrect() вернет значение cool, существовавшее при вызове функции.

0 голосов
/ 24 июня 2019

Ну, вам действительно нужно значение, а не переменная; и значение, к которому у вас уже есть доступ с использованием точечной нотации speechRec.resultString.

Вы можете попробовать что-то вроде этого:

// An modification that the post from above offers you, which is pretty good for this case. value-to-colours 
const colors = {
 0: '#dc3545',
 5: '#dc3545',
 10: '#dc3545',
 15: '#dc3545',
 20: '#dc3545',
};

function gotSpeech() {
    if (speechRec.resultValue) {
        zero.style.color = colors[speechRec.resultString];
    }
}

button.addEventListener("click", function(event) {
    resetround();
    speechRec.start();
    // Why are you passing the functions as string?
    // Better do this

    setTimeout(getComputerChoice, 3000);
    setTimeout(identifyHands, 3000);
    clearInterval(myInterval);
    myInterval = setInterval(function() {
        time--;
        if (time == -1) {
            button.innerHTML = "Again";
            clearInterval(myInterval);
            time = 4;
        } else {
            button.innerHTML = "Start";
            numbers.innerHTML = time;
        }
    }, 1000);
    setTimeout(guessedCorrect.bind(null, speechRec.resultString), 5000);
})

Если ваша функция guessedCorrect экспортирована из другого файла, я бы использовал функцию bind для создания новой функции с заданными параметрами. В противном случае, если у вас есть функция в том же файле, просто передайте функцию следующим образом:

setTimeout(guessedCorrect, 5000);

и внутри функции просто используйте глобальную переменную speechRec.resultString.

Примечание. Попробуйте использовать строгое сравнение (===) вместо абстрактного (==).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...