Беларусь, рогачёв |
Функции
Конструирование функции в момент передачи
Прием конструирования при передаче особенно удобен при сортировке массивов (мы его даже уже применяли, когда рассказывали о массивах):
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
О том, как справиться с подобной бедой, мы узнаем в следующем параграфе.