Опубликован: 23.12.2005 | Уровень: специалист | Доступ: платный | ВУЗ: Московский физико-технический институт
Лекция 5:

Функции

Конструирование функции в момент передачи

Прием конструирования при передаче особенно удобен при сортировке массивов (мы его даже уже применяли, когда рассказывали о массивах):

var arr = ["aaaaaaaa", "bbb", "cc", "dddd", "e", "gg"];
arr.sort(
   function(str1, str2){
      return (str1.length > str2.length) ?
         1 : ((str1.length == str2.length) ? 0 : -1);
   }
);
trace(arr.join(", "));

В результате получаем:

e, cc, gg, bbb, dddd, aaaaaaaa

то есть мы отсортировали массив по возрастанию длины строк. В этом примере привлекает то, что вся информация сосредоточена в одном месте: прямо в вызове метода sort мы и указываем, как именно надо сортировать.

"Опасная" рекурсия

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

a = {};
a.recProgressionSum = function(n){
   if (n < 1) return n;
   return n + this.recProgressionSum(n - 1);
}
trace("from a: " + a.recProgressionSum(5));
trace("from a: " + a.recProgressionSum(5.5));
b = {};
b.recFunction = a.recProgressionSum;
trace("from b: " + b.recFunction(5));
trace("from b: " + b.recFunction(5.5));

В результате выполнения этого кода мы получим следующее:

from a: 15
from a: 18
from b: 5
from b: 5.5

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

a = {};
a.recProgressionSum = function(n){
   if (n < 1) return n;
   return n + a.recProgressionSum(n - 1);
}
trace("from a: " + a.recProgressionSum(5));
trace("from a: " + a.recProgressionSum(5.5));
b = {};
b.recFunction = a.recProgressionSum;
trace("from b: " + b.recFunction(5));
trace("from b: " + b.recFunction(5.5));
a = {dddd: 1};
trace("from b: " + b.recFunction(5));
trace("from b: " + b.recFunction(5.5));

Этот код выводит

from a: 15
from a: 18
from b: 15
from b: 18
from b: 5
from b: 5.5

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

алексеи федорович
алексеи федорович
Беларусь, рогачёв
Тамара Ионова
Тамара Ионова
Россия, Нижний Новгород, НГПУ, 2009