Подтвердить что ты не робот

Есть ли недостатки в использовании анонимных функций в JavaScript? Например. использование памяти?

В какой-то момент в прошлом я читал что-то, что дало мне представление о том, что анонимные функции в JavaScript могут использовать удивительный объем памяти (потому что они несут всю текущую область вокруг них), тогда как named (static?) функции не имеют этой проблемы.

Я не могу вспомнить, где я это прочитал, поэтому я не могу вернуться и перечитать его и понять это для себя.

У меня возникли два вопроса:

  • Существуют ли ситуации, когда анонимные функции могут использовать достаточную память для того, чтобы ее стоило заботиться? (Если да, у вас есть пример?)
  • Существуют ли какие-либо другие недостатки анонимных функций (в отличие от названных/статических функций)?
4b9b3361

Ответ 1

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

Эта цепочка ссылок на внешние среды остается с каждой функцией, даже если функция передается в совершенно другую область.

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

Однако существуют и другие ситуации, когда анонимная функция расточительна.

Вот общий бит кода:

for( var i = 0; i < 100; i++ ) {
    (function( j ) {
        setTimeout( function() { console.log( j ); }, 1000 );
    })( i );
}

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

function setConsole( j ) {
    setTimeout( function() { console.log( j ); }, 1000 );
}

for( var i = 0; i < 100; i++ ) {
    setConsole( i );
}

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

http://jsperf.com/immediate-vs-named (Благодаря @Felix Kling для jsPerf. )

Таким образом, в отношении закрытия, в частности, да, накладные расходы, если вы поддерживаете закрытие некоторой постоянной ссылкой. Я бы сказал, что хорошо избегать этого, если это возможно, но не быть обсессивным. Иногда новая переменная среда, добавленная в цепочку областей видимости, является просто лучшим решением.


EDIT: Здесь статья из Google. В частности, см. Предотвращение ошибок с закрытием. для получения информации о влиянии производительности на расширение цепочки охвата и заявлении о том, что анонимные функции "медленнее", чем именованные функции.

Ответ 2

Я думаю, что вы, вероятно, читали о проблеме утечки памяти IE.

Посмотрите эту статью по этой проблеме.

В основном, в более старых версиях IE сборщик мусора не мог обрабатывать круговые ссылки с объектами DOM. Поскольку замыкания очень благоприятны для таких циклических ссылок, они могут легко привести к раздражающим утечкам памяти в IE.

Ответ 3

Это верно, из-за созданных закрытий. как правило, самая большая проблема с практикой - проблемы с производительностью IE (особенно более старые версии IE), которая имеет ужасный послужной список для правильной работы с ними.