![]() |
Функции внутри функций - почему это зло?
Добрый день,
извините за назойливость, но мне необходимо понять - почему плохо создавать функции внутри функций? И как правильно организовать следующий код? Код:
public function loadImg():Void { |
Код:
class имя класса { |
dashaaa, ну во-первых, приведенный вами код не будет работать, просто потому что onLoadError не принадлежит объекту oLoadListener. А вложенные функции плохи тем, что во первых, плывет область видимости и начинаются проблемы с обращением к различным свойствам и объектам, во вторых, вместо того, что создать метод один раз в памяти, он постоянно пересоздается новый.
|
Дело в том, что функция просто выполняется при вызове, и выполнившись, возвращает результат или меняет чтото вне себя. После того, как она выполнилась, все ее внутренние переменные больше недоступны, точнее их уже нет. Все эти переменные - mclLoader, oLoadListener, и функция onLoadError() существуют лишь до тех пор, пока выполняется loadImg(), потому что это ее внутренние переменные. Они как пассажиры пролетающего вагона - могут разговаривать друг с другом, но Вы, на полустаночке), ни словом с ними не перекинетесь. Пролетая мимо, они Вам могут крикнуть "загрузи картинку и отдай Васе на пятом сиденье", но пока Вы сбегаете за картинкой - ни Васи, ни сиденья.
(из моего поста могло создаться впечатление, что дело во времени, но на самом деле конечно в областях видимости - т.е. нормальная организация подразумевает, что Вася стоит с Вами на полустаночке. Т.е. функция не должна быть внутри другой функции) |
Цитата:
Но вообще-то идея ясна, спасибо. __etc, спасибо, с областью видимости уже столкнулась, и то, что метод пересоздаётся - это аргумент. Wolsh, спасибо, понятно =) |
создавайте экземпляр MovieClipLoader в конструкторе класса
|
Функция внутри функции - это нормальное явление, просто надо знать для чего это нужно.
То, что "поезд уходит" тоже не совсем верно: Код:
function A(){ |
хы-хы
в делигаторе функция внутри функции, но там правда ссылка на неё живая |
Цитата:
|
Цитата:
Цитата:
|
chingachgoog, мы с Вами как-то спорили про клипы и кнопки, так вот это примерно из той же серии. Когда человек чётко представляет что и как работает, он безусловно просто выберет действительно оптимальный вариант для решения своей задачи. Например, создаст ядерное оружие вместо электростанции))) Правда при этом другие будут на него косо смотреть, примерно как я смотрел бы на коллегу, принёсшего мне такое вот рэндзю из активаций. Почти всегда можно найти способ, в народе именуемый хаком, и взломать головы своим соратникам, пытающимся где-нибудь в 2659-й строке понять, откуда что взялось. А можно просто сделать так, как удобно, понятно и предсказуемо. Хитрые головоломные ходы должны использоваться только там, где без них никак. Делегате - да, отличный пример такой необходимости. Для упрощения этой необходимости он и создан))))
|
Область видимости никуда "не плывет" и почему должна "расходоваться память"? Просто область видимости иная (собственно это и причина применения) и память занята функцией временно.
Но механизм действия функции в функции очень сложен, придумать для чего это надо - не просто. Потому распространен стереотип - "это зло", "*****код" и т.д. А это просто еще одна из редко используемых возможностей флеша, к тому же, мало кому понятная. PS Попытался вспомнить когда я такую конструкцию применял на практике - не получилось :) |
chingachgoog, можно у себя в подъезде гадить, утверждая, что со временем испарится и выветрится, а можно ходить в специально отведенные для этого места. И так называемый стереотип, на является примером ясного и красивого написания кода, который не вызывает проблем и вопросов "а почему не работает", также как вшивание шрифта через библиотеку. А расход памяти создать можно запросто, сохранив ссылку на функцию.
|
iNils, я уловил аналогию между словами "*****код" и "гадить в подъезде", но не между "гадить в подъезде" и "вложенные функции".
Да, вложенные функции не есть "ясное написание кода, которые не вызывает проблем". Но разве, например, умножение на двое побитовым сдвигом - это "ясное написание кода, которое не вызывает проблем"? В таком случае умножение побитовым сдвигом - это "гадить в подъезде", т.к. есть "специально отведенное место" - простая запись "*2". |
chingachgoog, а при чем тут побитовый сдвиг? Это как школьник, которого мапа ругает за двойку, начинает оправдываться словами "А вот у Васи родители его за двойку не ругают". Не подтягивать в качестве примера то, о чем речь и не заходила, вынуждая нас оправдываться за кого-то там, кто так делает и тут вообще не присутствует.
Побитовый сдвиг используется тогда, когда нужно думать именно категорией сдвига, а не умножения. Как пример, работа с RGB и его составляющими. |
Функции в функции не считаю чем-то из ряда вон. В некоторых случаях такая реализация только улучшит читаемость кода.
http://habrahabr.ru/blogs/webdev/38642/ - советую прочитать про то, как это используется в javascript`е |
Речь зашла о "ясном написание кода, которое не вызывает проблем". И тут побитовый сдвиг (примененный, скажем для увеличения производительности расчета, по сравнению с простым *2) никакой ясности не внесет и запросто вызовет проблемы. Ну и что? Применять побитовый сдвиг только при работе с RGB?
Нельзя Васи ставить двойку за то, что он решил задачу способом иным, чем предполагал учитель: Цитата:
|
Цитата:
Цитата:
|
Цитата:
add: Цитата:
|
chingachgoog, спутать пример с двойкой, смысл которого в том, что надо за себя отвечеть, с примером о низкой оценкой за не закостенелость мышления, является либо полным не пониманием о чем идет речь, либо разведением демагогии. Если первое, то ладно, люди ошибаются, если второе, то с этим во флейм, а здесь это будет пресекаться.
|
Не, ну если измерять высоту здания веревкой с привязанным грузом - пример незакостенелости мышления в пику показаниям барометра - то да, дошли до демагогии и я самоудаляюсь. chingachgoog, Вы даже не поняли, что в своей борьбе за свободу индейцев привели пример самого настоящего быдлокода, и то что его автор - Нильс Бор - отнюдь не делает чести ни "коду" ни Бору. Если бы товарищ Бор в этой ситуации предложил НОВЫЙ метод, тогда да, можно поговорить о незакостенелости. А все эти "методы" оба физика прекрасно знали, просто не были таким быдлом, чтоб забивать микроскопом гвозди. В следующий раз для демагогии выбирайте примеры поудачней.
|
Так. Ставим жирную точку . в вопросе о двойках, подъездах, смещениях и тп. И возвращаемся к вопросу о функции в функции.
Если есть примеры оправданного применения, то вперед. |
Если требуется функцией обработать локальные переменные другой функции, то ничего лучше встроенной функции нет - можно не беспокоится о перекрывании имен переменных.
|
Пример где?
|
OK. Применение замыканий (closure), упомянутое †‡Paladin‡†, иногда способно улучшить читабельность. Пример два года висит в моей подписи))) Думаю, никто не будет спорить что запись
Код:
mdb.onPress = playSong("MyDyingBride"); |
Вычисления с локальными переменными в функции А должны быть достаточно громоздкими, чтобы потребовалась функция В. Это теория, а практического примера, как я говорил, у меня нет. Наверное еще не попадалась необходимая громоздкая обработка внутренних переменных вкупе с необходимостью изолировать ее.
Код:
var per="внешняя"Wolsh, у вас выходит аналог делегата, а это типа "не считается" :) Код:
mc1.onPress=f_set("1") |
Данный код годится только для понимания, как это работает. А практической ценности в нем ноль. Там не только отсутствие фантазии в названии переменных (вспоминается D12 со своими z zz zzz zzzzzzz), но и потенциальная путаница в самих переменных.
|
Смысл инициализировать каждый раз заново функцию - непонятен.
Объяснить довольно сложно, почему так нельзя(не следует, не правильно и т.д.). И простит меня iNils: но как объяснить человеку, что казарму следует мыть половой щёткой, а не зубной. Это довольно сложно. И доказать тоже. Как минимум при применении методов "инициализация функции в функции" получается избыточная работа программы. При больших и серьёзных проектах это не допустимо. А если боишься забыть или потеряться: 1) Называй функцию вменяемо - благо от размера имени функции во Flash ничего не меняется 2) Пиши комментарии Такие вопросы часто встречаю у своих учеников(правда по PHP). |
Цитата:
Практическую ценность я не встречал, а специально выдумывать не охота. |
Цитата:
|
старые песни о главном
Подскажите, как в такой ситуации правильно организовать функции, чтобы не было проблем с вложенными функциями и с областями видимости:
Код AS1/AS2:
|
Код:
import mx.utils.Delegate; |
Спасибо большое! Я до этого понятия не имела о Delegate.
|
А зачем использовать Delegate, по-моему есть более простой и удобный способ:
Код AS1/AS2:
|
faust.d503, это кривой и неудобный способ.
|
__etc
Расскажите, чем он кривой и неудобный и чем лучше Delegate. Нет конечно можно подключить дополнительный класс, чтобы повысить вес программы, но зачем. Кстати написать функцию прямо внутри конструктора, тоже вполне логичный способ, если парсер используется один раз. Ибо размножать количество методов и переменных класса пусть, и приватных, не всегда хорошо. |
Такой обработчик нельзя удалить, он будет висеть в памяти до упора, плюс требует self-ссылки, которая тоже живет в памяти, потому что живет функция.
|
Цитата:
Код AS1/AS2:
|
Да, но тогда анонимная функция с большой вероятностью останется жить, потому что есть self-ссылка, используемая внутри.
|
О, уже костыли пошли, а было "более простой и удобный способ".
|
| Часовой пояс GMT +4, время: 16:25. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.