Как решить Var вне области видимости в вызове setTimeout

Я пытаюсь вызвать setTimeout из обратного вызова setInterval:

function callback()
{
   //assign myVar
   var myVar = document.getElementById("givenID");
   //...
   //now wait 2 secs then call some code that uses myVAr
   setTimeout("myVar.innerHTML = 'TEST'", 2000);
}

setInterval("callback();", 10000);

setInterval работает должным образом, но вызов setTimeout не работает. Я предполагаю, что проблема связана с тем, что я ссылаюсь на переменную (myVar), которая не входит в область действия.

Как лучше всего решить эту проблему?

Использование замыканий, как я указал ниже, может обойти это, внутреннее замыкание имеет доступ к области внешнего замыкания.

FlySwat 26.10.2008 05:37

Я, должно быть, что-то упускаю - вы пытаетесь сэкономить производительность, предварительно вычисляя myVar? Почему бы не setTimeout ("document.getElementById (" givenID "). InnerHTML = 'TEST'", 2000); ?

buti-oxa 26.10.2008 05:46

Не используйте кавычки с setTimout / setInterval, это заставляет среду выполнения JS вызывать Eval, который запускает код в новом контексте, отсюда и проблема области.

FlySwat 26.10.2008 05:48

Приветствую всех - я многому научился из этого вопроса

JohnIdol 26.10.2008 06:01

Мне кажется, это работает. Что вы имеете в виду под «провалом»? И какой браузер / etc. ты используешь?

jtbandes 26.10.2008 04:48

Оповещение также работало для меня с предыдущим примером - поэтому проблема не связана с установленным там setTimeout, спасибо за указание, я отредактировал вопрос.

JohnIdol 26.10.2008 05:31
Поведение ключевого слова "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) для оценки ваших знаний,...
12
6
15 834
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Запустите его в Firefox и проверьте Инструменты | Консоль ошибок. если setTimeout не работает, он может сказать вам, почему там.

Также попробуйте заменить "someFunction();" на "alert('hi')" (без точки с запятой) и посмотрите, работает ли это. Если это так, проблема значительно сужается.

ура - я сделал это и заметил, что проблема не связана с setTimeout - см. править

JohnIdol 26.10.2008 05:35

В качестве наилучшей практики старайтесь не использовать строки в качестве параметров для setTimeout и setInterval, потому что это вызовет eval ... Использование следующей формы также может облегчить понимание / отладку этой проблемы:

setInterval(function () {
    // do stuff
    // ...
    // now wait 2 secs then call someFunction
    setTimeout(someFunction, 2000);
}, 10000);
Ответ принят как подходящий

Это идеальный кандидат на закрытие:

setInterval(
    function ()
    {
       var myVar = document.getElementById("givenID");
       setTimeout(
          function()
          {
              // myVar is available because the inner closure 
              // gets the outer closures scope
              myVar.innerHTML = "Junk";
          },2000);
    }, 10000);

Ваша проблема связана с областью действия, и это поможет обойти это.

Таким образом, демонстрируется отличная причина не передавать строки в качестве параметров в setTimeout и setInterval! :-)

Andrew Hedges 26.10.2008 05:52

Это отличная новость - кажется, что в каждом примере SetTimeout и SetInterval параметр является строкой; не знал, что вы можете просто пройти закрытие.

thepeer 27.01.2011 17:18

это ДЕЙСТВИТЕЛЬНО хороший кандидат для тех руководств по закрытию, которые так популярны на данный момент ....

Alex 29.11.2011 03:50

У меня была аналогичная проблема. Проблема заключалась в том, что я пытался вызвать метод изнутри через setTimeout (). Примерно так, У МЕНЯ НЕ РАБОТАЛО:

function myObject() {

   this.egoist = function() {
      setTimeout( 'this.egoist()', 200 );
   }

}

myObject001 = new myObject();
myObject001.egoist();

Следующее ТАКЖЕ НЕ РАБОТАЛО:

... setTimeout( egoist, 200 );
... setTimeout( egoist(), 200 );
... setTimeout( this.egoist, 200 );
... setTimeout( this.egoist(), 200 );
... setTimeout( function() { this.egoist() }, 200 );

Решением было использовать оператор with () следующим образом:

function myObject() {

   this.egoist = function() {
      with (this) { setTimeout( function() { egoist() }, 200 );}
   }

}

myObject001 = new myObject();
myObject001.egoist();

Конечно, это бесконечный цикл, но я здесь о другом.

Надеюсь это поможет :)

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