![]() |
|
Модераторы: Sardar, Aliance |
![]()
|
|
| Се ля ви |
|
||||
![]() Java/SOAрхитектор ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 5 Всего: 127 |
Не перестаю удивляться JavaScript`у.
Вот, тут заметил, что, с одной стороны, аргументы конструкторов автоматически попадают в категорию private-полей:
С другой стороны, оно не просто является private-полем, но ещё и является неистребимым - попытка их удалить, что бы не таскать за собой, приводит к неудаче:
Так что на этот раз придётся Магомету идти к горе и обзывать входящие параметры конструктора так, как вы хотите назвать private-поля, ими инициализируемые. Это не есть интуитивно понятно, если не знать этой хитрости, но если её знать и грамотно использовать - это может заметно сэкономить объём вашего кода ;) -------------------- |
||||
|
|||||
| Се ля ви |
|
|||
![]() Java/SOAрхитектор ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 5 Всего: 127 |
Насчёт delete x проверил - вообще-то ни одно private-поле так не удалишь, так что нужно об этом помнить, когда его создаёшь. (Для освобождения памяти, который занимает объект, доступный по ссылке, можно присвоить ссылке значение null, но на самом деле это не равнозначно отсутствию ссылки - ссылка будет всё равно).
Но если вам на самом деле не нужен тот аргумент, который вы приняли в конструкторе, в последствии - то следует отказаться от именованных аргументов вообще и обращаться к ним по индексам "массива" arguments - это гарантирует удаление ссылок после выполнения конструктора. -------------------- |
|||
|
||||
| Се ля ви |
|
||||
![]() Java/SOAрхитектор ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 5 Всего: 127 |
В общем, резюме такое: за конструкцией
на самом деле стоит следующее:
-------------------- |
||||
|
|||||
| dsCode |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 565 Регистрация: 8.9.2007 Где: Saint-Petersburg Репутация: 19 Всего: 26 |
неа, скоп внешней функции "оседает" в замыкании при создании замыкания (единственная разница (проблема), что вы не сможете различить arguments внешней функции по этому имени ("arguments"), т.к. объект с таким именем "не свободный" (т.е. будет найден сразу в скопе замыкания)):
любым var'ам ставится {DontDelete} (и нет никаких различий между "просто private-полями" и "неистребимыми" =)) объявите глобальную переменную var a = 10; - alert(window['a']); - она никакая не приватная, delete window['a'] - ничего не получится. в общем, резюме опять лежит в 10.1.3 Variable Instantiation и то, что вы написали var x = arguments[0]; от первого случая ничем не отличается, кроме дополнительной работы - и там, и там x станет свойством Variable Object'a (правда, объявление undefined'ых var'ов внутри функции никак не "перезатрет" формальный параметр):
Но с другой стороны, объявление функции (которая тоже будет свойством Variable Object'a) имеет больший приоритет и перезаписывает var'ы:
Это сообщение отредактировал(а) dsCode - 30.6.2008, 19:38 |
||||||||
|
|||||||||
| Се ля ви |
|
|||
![]() Java/SOAрхитектор ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 5 Всего: 127 |
Мда... А ты уверен, что arguments дочерней функции именно перекрывает, а не выталкивает arguments родительской? Ведь поведение этого фрагмента кода можно объяснить и по-другому - что ты оставляешь дополнительную ссылку на arguments родителя и в следствии этого она не забирается сборщиком мусора, а не было бы ссылки - может, собралась бы или была бы замещена новым arguments?.. Но если правда то, что ты пишешь, тогда, блин, я не знаю, что себе думали создатели спецификации... Получается, что использовать аргументы в конструкторах и в функциях, которые генерят другие функции - это таскать за собой эти аргументы хвостом в течении всего жизненного цикла этих объектов и этих генерируемых функций... А если они нафиг не нужны - их даже прямо удалить нельзя... :((( Как-то это расточительно выглядит... :( Получается, что единственный выход - обnullять вручную формальные параметры в тех случаях, когда они могут попасть в closure - что бы хоть ненужные объекты память не захламляли. При чём обnullять как по именам, так и в "массиве" arguments, что бы ссылок на эти объекты не оставалось. Тогда мы будем таскать за собой пустые ссылки, но хотя бы не будем таскать объекты... Хотя выглядит это, конечно, не очч... :((( -------------------- |
|||
|
||||
| dsCode |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 565 Регистрация: 8.9.2007 Где: Saint-Petersburg Репутация: 19 Всего: 26 |
ага
именно так работают замыкания; на момент использования внутренней функции, внешней уже может не быть, поэтому весь (!) скоп (набор variable object'ов (VO)) приплюсовывается к скопу замыкания (это и есть scope-chain, который хранится во внутреннем свойстве [[scope]]) "именованные" и индексные взаимозаменяемы:
а вот, когда обnullять - до или после определения замыкания - не важно - переменная x (пример ниже) - "свободная" для VO функции b (т.е. ее нет в родном VO функции b), поэтому будет искаться по цепи скопов и найдется в VO функции a (которой уже может не быть); мы обnullяем свойство x VO функции a, поэтому alert выдает null, а не 5:
Это сообщение отредактировал(а) dsCode - 1.7.2008, 12:08 |
||||||
|
|||||||
| Се ля ви |
|
||||
![]() Java/SOAрхитектор ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 5 Всего: 127 |
Тогда для предотвращения утечек памяти можно просто в конце каждой функции, где может произойти "короткое замыкание" ;) вставлять примерно следующее:
P.S. Кстати, обнаружил, что var`ы - чрезвычайно живучи. До этого думал, что они по аналогии с Java - умирают когда выходишь за пределы любого блока, в котором они объявлены, но оказывается - нифига:
Так что это верно только для функции в целом, но не для её под-блоков. Поэтому я в качестве счётчика в предыдущем примере использовал "подручный материал", а не стал заводить новую переменную, как я это обычно делаю в той же Java. -------------------- |
||||
|
|||||
| dsCode |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 565 Регистрация: 8.9.2007 Где: Saint-Petersburg Репутация: 19 Всего: 26 |
конечно, нифига =) но, в версии 1.7 алтернативой var'ам (чей локальный скоп - функция), появились let'ы, которые создают локальный скоп в нужном месте (их как раз можно использовать в циклах) |
|||
|
||||
| Се ля ви |
|
|||
![]() Java/SOAрхитектор ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 5 Всего: 127 |
Здорово! Жаль только, что, согласно WikiPedia`и, поддерживается всё, что дальше JS 1.5 - только в Gecko и Safari... :((( -------------------- |
|||
|
||||
| Ghirik |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 919 Регистрация: 26.3.2007 Репутация: 13 Всего: 20 |
В JavaScript-е var для того и есть чтобы задать живучесть объявляемуму элементу. И видимо, по задумке сочинителей, он должен поддерживать контекст в котором задается, но соблюсти это правило удается не всем создателям интерпретаторов. Это в большей мере касается вложенных функций и головоломок, вроде наследования свойств, объявленных не понятно под каким соусом. Вообще, манера программирования в древовидном стиле, меня почему то бесит, что то есть в этом нездоровое. Зачем? Потом не можем разобраться кто и где родился, и сколько проживет. Не проще ли просто избегать таких ситуаций? Конечно здорово ощущать себя суперменом, когда написал функцию, которая имеет пять степеней вложенности и ни где не замыкает. Но это только для тренировки, или для нечитаемости. Последний момент конечно очень важен, если научишся так мыслить, вложенно, типа своей стилистики.... Но оно того не стоит.
Ну да, давайте ещё леты поддержим во всех браузерах! Для какой такой экстренной помощи потребовалось? Блочность данных и так можно спокойно обеспечивать и за ненадобностью удалять, всё вместе со всеми объявлениями. Если создавать все элементы навешивая их на любой действующий объект дерева, то при удалении самого объекта память высвобождается в любом браузере сразу. Там уже действуют обычные DOM-правила. Такой подход очень удобен при работе с html-элементами. Главное, ни var ни let вообще не нужны. Создавайте любой массив свойством к имеющемуся в дереве объекту. Тысячу массивов... Хакните элемент, - и массивы хакнутся, и память очистится. А передавать параметры обработчикам вообще не потребуется, вы их до того повесите на этот элемент свойствами. Мне нравится такой подход. -------------------- Отдадим всё клиенту, пускай его машина мучается... |
||||
|
|||||
| dsCode |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 565 Регистрация: 8.9.2007 Где: Saint-Petersburg Репутация: 19 Всего: 26 |
Хороший подход, только обращение к свойствам DOM-объектам - медленнее, чем к переменным JS. Простой пример: при очень больших циклах целесообразно (для оптимизации скорости) вынести свойство length в переменную (т.к. оно вычисляется на каждой итерации цикла):
А теперь, возвращаясь к теме "неистребимых" var'ов (чтобы более точно сказать о них) - в 10.2.2 Eval Code ничего не сказано про {DontDelete}, поэтому var'ы, полученные через eval, можно удалить.
Это сообщение отредактировал(а) dsCode - 8.7.2008, 22:53 |
||||
|
|||||
| Се ля ви |
|
|||
![]() Java/SOAрхитектор ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 5 Всего: 127 |
А ещё можно let`ы эмулировать так:
-------------------- |
|||
|
||||
![]()
|
| Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | JavaScript: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |