Добавляем...


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

n! = n * (n-1) * (n-2) * ... * 1.

Так, в соответствии с этим определением, мы имеем 5! = 5*4*3*2*1, т.е. 120. Напомним также, что значение 0! определяется равным 1, а факториалы отрицательных чисел не определены. Используя прямолинейный подход, можно написать рекурсивную функцию для вычисления факториала. Так, определяемая ниже функция factorial продолжает вызывать себя с все меньшими значениями, пока не будет достигнуто базовое значение 0, при котором результаты возвращаются "наверх" для завершения вычислений.

function factorial(n)
{
if (n == 0)
return 1;
else
return n * factorial (n-1);
}

Передавая функции положительное значение, убеждаемся, что alert(factorial (5));
выдает требуемый результат: "120"

Однако, если передать функции отрицательное значение, рекурсия будет продолжаться неопределенно долго. Вот какую ошибку генерирует в этом случае Internet Explorer:
выдает требуемый результат: "Stack overfow at Ine: 15"

Чтобы избежать подобных проблем, можно просто добавить в функцию подходящий оператор if.
    Появление сообщения об ошибке в некоторых рекурсивных функциях возможно также просто потому, что рекурсия происходит слишком долго, даже если сами вычисления вполне допустимы (т.е. в конечном счете должны завершиться). Причина в том, что рекурсивные вычисления могут исчерпать имеющиеся ресурсы, поскольку информация о функциях, не завершивших работу, хранится в стеке их вызова.
    Решение проблемы вполне прямолинейно, хотя и не всегда элегантно: следует переписать рекурсивную функцию в итеративной форме. Вот как можно переписать функцию factorial:

function factorial(n)
{
if (n >= 0)
{
var result=1;
while (n > 0)
{
result = result * n;
n--;
}
return result;
}
return n;
}

В пределах Web-страниц рекурсивные функции JavaScript используются редко. Но мы еще вернемся к рекурсии позже, когда будем рассматривать дерево документа (X)HTML в рамках объектной модели документа.
Использование функций
    Перед завершением этой главы давайте немного отклонимся от темы и поговорим э практике использования функций в JavaScript. Следующие советы предлагаются в качестве рекомендаций по программированию и должны способствовать созданию программного кода, более простого для понимания и сопровождения.

Определяйте все функции для сценария сразу. Причина такой рекомендации очевидна: пред тем как вызывать функцию, нужно быть уверенным в том, что она определена :o! прочитана браузером. Кроме того, если мы определим все функции, используемые программным кодом, в одном месте, эти функции в случае необходимости легче найти.

Правильно выбирайте имена для функций. При выборе имен для функций и переменных нужно быть внимательным. Функции и переменные разделяют одно пространство имен, поэтому нельзя использовать для них одинаковые имена. Хорошо начинать имена всех функций с префикса "June" или какой-то другой строки или буквы. Так, если у нас есть переменная с именем hello и мы хотели бы иметь функцию с соответствующим именем, мы должны использовать funcHello.

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

var х = 5;
function х()
{
alert("Я - функция!");
alert(typeof х) ;
}

Можно ожидать, что диалоговое окно сообщит о том, что х является функцией или, что более вероятно, объектом, поскольку именно определение функции указано в сценарии последним. Но, как оказываеться, х будет иметь тип number, т.е. оказывается числом:
Вывод становится понятным, если вспомнить о правилах создания функций и переменных. Функции создаются при анализе сценария, тогда как переменные создаются во время его выполнения. Данный пример является достаточно умозрительным, но он иллюстрирует важность понимания того, как создаются те или иные вещи в JavaScript.

Используйте функции из внешних файлов .js, но будьте внимательны. Многие программисты любят размещать функции во внешних файлах, но перед вызовом такой функции нужно проверить, что функция доступна. Например, если есть два файла (lib1.js и Ub2.js), в каждом из которых вызываются функции, находящиеся в другом файле, необходимо проверить, доступны ли соответствующие функции, поскольку браузер может закончить загрузку одного сценария раньше другого. В главном документе мы должны присвоить значение false переменным, характеризующим загрузку файлов:

var liblLoaded = false;
var lib2Loaded = false;

Затем, в каждом из загружаемых документов последняя строка должна устанавливать соответствующей переменной значение true. Используя такой подход, перед вызовом функции, находящейся в соответствующем файле, следует проверить значение liblLoaded или lib2Loaded. Например,

if (lib2Loaded)
doSomething(х,у,z)

    Чаще всего такие усилия оказываются излишними, но создатель программы на JavaScript должен учитывать порядок загрузки документов, а также возможные последствия вызова определенных частей сценария до полной загрузки документа.


добавить комментарий
(без перезагрузки и регистрации)


10 случайных разделов

Что ищем на сайте ?


Примеры кода на сайте







@ 2008-2011 Amber
При использовании материалов ссылка на сайт обязательна
Яндекс.Метрика