Простая задача определения функции javascript

function First () {
setTimeout("Second()", 50)
};

function Second () {  //I'm very confident this conditional works fine
 if  (document.getElementsByClassName("l")[0].href ==
      document.getElementById("myFrame").getAttribute("src"))  
   {  
   First();                                       
   }
 else
   {
   var newLink = document.getElementsByClassName("l")[0].href;        //
   document.getElementById("myFrame").setAttribute("src", newLink);
   }};

First ();

Проблема в том, что когда First() определен, я получаю ошибку, что Second не определен. Как это можно решить?

3 ответа

Решение

Обновить

Ваш обновленный код сильно отличается от вашего исходного кода. Кажется, проблема в том, что вы передаёте строку setTimeout (что удивило меня, но было легко воспроизведено). я бы поменял

function First () {
    setTimeout("Second()", 50)
};

в

function First () {
    setTimeout(Second, 50);
}

... или если вам нужно передать параметры Second:

function First() {
    setTimeout(function() {
        Second(param0, param1);
    }, 50);
}

(Обратите внимание, что нет необходимости в ; в конце объявления функции, но один после setTimeout не пойдет не так [вам на самом деле это не нужно, ужас "вставка точки с запятой" вставит его для вас в этом случае, но...].)

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

Оригинальный ответ

Что касается ответа ниже, код, указанный в вашем вопросе:

function First() {Second();};
function Second() {First();};

Этот код будет работать просто отлично. Это бесконечный цикл (ну, не бесконечный, потому что в итоге у реализации не будет больше стекового пространства для адресов возврата), но пока он не взорвется из-за этого, он будет работать нормально. пример

Он потерпит неудачу, если ваш реальный код будет выглядеть примерно так:

var First = function() {
    Second();
};
First();
var Second = function() {
    First();
};

... поскольку это очень отличается, в нем используются выражения функций (которые обрабатываются как часть пошагового кода), а не объявления функций (которые обрабатываются при входе в область действия перед любым пошаговым кодом) и это вызов First до Second определено. Посмотрите этот другой ответ здесь в Stackru для более подробной информации о различии между выражением функции и объявлением функции.

Хорошо, я думаю, что вижу твою проблему. Могу поспорить, твой код обернут внутри функции, верно? Тогда не было бы такой вещи, как функция Second.

Это не будет работать:

(function() {
    function First () {
        setTimeout("Second()", 50)
    }
    function Second () {
        alert('hi!');
    }
    First();
})();

Но это будет работать:

(function() {
    function First () {
        setTimeout(Second, 50)
    }
    function Second () {
        alert('hi!');
    }
    First();
})();

Я только что попробовал ваш код и вызвал "Second();" первый. В Chrome все работало нормально. Конечно, это будет продолжаться вечно.

В JavaScript переменные связаны очень поздно при вызове функции. Глобальный объект - это просто еще одна переменная, которая также "связана" очень поздно. Все может измениться в любое время (асинхронно), поэтому функция не должна требовать наличия другой функции. "Отсутствующая" функция может быть просто добавлена ​​каким-либо другим механизмом непосредственно перед ее вызовом. Только непосредственно перед выполнением функции JS-среда выполнения должна проверить, доступны ли эти функции в области.

Вот почему он работает в Chrome. В Javascript вы на самом деле делаете что-то вроде этого:

var GLOB = this; // bind global obj to variable

GLOB["First"] = function() {
   GLOB["Second"]();
};

GLOB["Second"] = function() {
   GLOB["First"]();
};

Вызов GLOB["Second"](); работает как брелок в Chrome (и, конечно, циклы). может быть, ваш браузер /JS-реализация /dev-tool более ограничен в отношении определений функций, и давайте не будем использовать функции до их определения.

Тогда вы можете использовать это obj["funcname"] = function() {} синтаксис, который делает так же, как function funcname(){}, но не может быть обнаружен как ошибка вашим "сломанным" JS-интерпретатором.

Надеюсь, это поможет, Юве

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