Как получить список функций в файле javascript?

Я пытаюсь собрать функцию включения стиля php для javascript. Маршрут, по которому я иду, - через XMLHttpRequest. Включенный файл загрузится, но функции в этом файле будут недоступны, поскольку их область действия ограничена вызывающей их функцией.

Я наткнулся на эту статью, которая преследует аналогичную цель, но требует, чтобы кодировщик указал какие функции они требуют заранее, в то время как я хотел бы просто включить файл и автоматически добавить функции объекта окна.

вот мой прогресс

function twinkle(){

    getXMLHTTPObj("twinkle/test.js");

    // A simple function inside test.js
    includedFunc();

}


// XMLHttp Stuff lifted from he Apple tutorial

var req;
function getXMLHTTPObj(url) {
    req = false;
    // branch for native XMLHttpRequest object
    if(window.XMLHttpRequest && !(window.ActiveXObject)) {
        try {
            req = new XMLHttpRequest();
        } catch(e) {
            req = false;
        }
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
        try {
            req = new ActiveXObject("Msxml2.XMLHTTP");
        } catch(e) {
            try {
                req = new ActiveXObject("Microsoft.XMLHTTP");
            } catch(e) {
                req = false;
            }
        }
    }

    if(req) {
        req.onreadystatechange = processReqChange;

            // Set to False so javascript waits for the included functions 
            // to become available 
        req.open("GET", url, false);
        req.send("");
    }

    return req;
}

function processReqChange() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            eval(req.responseText);
        } else {
            alert("There was a problem retrieving the XML data:\n" +
                req.statusText);
        }
    }
}

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

Любые идеи? Есть ли какое-то свойство или функция javascript, к которым я могу получить доступ, чтобы получить список функций в файле?


person gargantuan    schedule 10.03.2010    source источник
comment
Этот вопрос (тот, который я недавно задал) кажется дубликатом и имеет несколько хороших ответов: stackoverflow.com/questions/11279441/   -  person Anderson Green    schedule 02.07.2012


Ответы (4)


Измените способ объявления своих функций, и это должно решить проблему области видимости. Вместо:

function add(a, b) 
{                     
    return a + b;
} 

сделай это:

var add = function(a, b) 
{                     
    return a + b;
}   
person D'Arcy Rittich    schedule 10.03.2010
comment
Закрыть! Я выбрал window.includedFunc = function(){ ... }, который отлично решает эту проблему. - person gargantuan; 10.03.2010
comment
@gargantaun: вы должны опубликовать это как ответ - person Josh; 10.03.2010
comment
Если вы добавите это к своему ответу, я могу принять это. (принимать немного правильные ответы — это оплошность?) - person gargantuan; 10.03.2010
comment
@gargantaun: единственный недостаток в том, что все глобальные функции должны быть объявлены таким образом. Кажется глупым делать это только потому, что вам не нравится метод DOM, который будет работать корректно без изменения требуемого файла. - person Andy E; 10.03.2010
comment
@josh: Я чувствую себя плохо всякий раз, когда мне приходится отвечать на свои вопросы, особенно вскоре после того, как я их задал. Если OrbMan не отредактирует свой ответ, вы можете его принять. - person gargantuan; 10.03.2010
comment
@Andy: Вы, вероятно, правы, но для проекта, который я имею в виду, который в основном будет большой библиотекой объектов Javascript, этот метод создает хорошую визуальную подсказку о том, над каким файлом я работаю. Javascript не имеет такого визуального различия, когда дело доходит до ООП. - person gargantuan; 10.03.2010
comment
Мой метод всегда работал у меня при использовании Prototype, возможно, он творил какую-то магию за кулисами. Я не могу проверить ваш метод прямо сейчас, поэтому, если хотите, опубликуйте свой собственный ответ. - person D'Arcy Rittich; 10.03.2010

Достаточно просто использовать DOM для добавления необходимого скрипта:

function include(jsFile)
{
    var sEl  = document.createElement("script");
    sEl.type = "text/javascript";
    sEl.src  = jsFile;
    document.getElementsByTagName("head").appendChild(sEl);
}

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

person Andy E    schedule 10.03.2010
comment
И если загрузка вызывает у вас проблемы, добавьте в конец каждого сценария функцию, которая вызывает какой-либо пользовательский обработчик загрузки, то есть: scriptFinishedLoading('nameofThisScriptFile.js'); - person Josh; 10.03.2010
comment
Я упомянул об этом в другом комментарии... но в этом методе есть что-то, что мне не нравится. Это может быть иррационально. Но ответ OrbMan все равно поставил меня на правильный путь, так что проблема решена. - person gargantuan; 10.03.2010
comment
@gargantaun: мне кажется более иррациональным изменять источник во включенном файле, чтобы использовать window.funcName = function () {} для каждой глобально объявленной функции. - person Andy E; 10.03.2010
comment
@Andy: Извините, я повторяюсь здесь в двух ответах ... но вы правы, мой путь, вероятно, в большинстве случаев неправильный, но для проекта, над которым я работаю, который является библиотеки объектов Javascript, этот метод обеспечивает удобную визуальную подсказку о том, над каким типом файла я работаю, чего обычно не хватает в javascript. И самое главное, теперь я знаю, что можно сделать это таким образом. Сложится ли это к лучшему или нет, это другой разговор. - person gargantuan; 10.03.2010
comment
@gargantaun: Если вы делаете это таким образом, я бы рассмотрел пространство имен. Это включает в себя создание глобальной объектной переменной в основном файле, а включенные файлы добавляют классы, методы и свойства в это пространство имен при их оценке. Это почти то же самое, что и window.funcName = function () {}, вы просто используете свое собственное пространство имен вместо того, чтобы загрязнять объект window. - person Andy E; 10.03.2010
comment
@Энди: Это именно то, что я искал. Я просто еще этого не знал. Ваше здоровье. - person gargantuan; 10.03.2010

OrbMan указал мне правильное направление в этом вопросе, но решение этого конкретного метода включения файлов Javascript требует, чтобы функции были определены по-другому; нравится

window.myFunction = function(){ 

    alert("Hey There!") 

}

Потенциальным преимуществом этого является то, что любые функции во включенном файле, которые объявлены обычным способом, инкапсулированы, поэтому они доступны только для window.functions из этого файла... насколько я могу судить.

person gargantuan    schedule 10.03.2010

Вместо загрузки файла JavaScript через AJAX, почему бы не создать тег <script> и не вставить его на страницу? Это позволит анализировать JavaScript в глобальной области видимости. Посмотрите, как работает функция require Scriptaculous.

person Josh    schedule 10.03.2010
comment
Мне почему-то такой подход не нравится. Я не знаю почему, и это полностью мое личное предпочтение, но этот способ кажется мне более аккуратным. - person gargantuan; 10.03.2010