Вопрос. Кажется, что у Closures много преимуществ, но каковы недостатки (утечка памяти? проблемы с запутыванием? увеличение пропускной способности?)? Кроме того, правильно ли я понимаю замыкания? Наконец, после создания замыканий можно ли их уничтожить?
Я немного читал о закрытии Javascript. Я надеюсь, что кто-то немного более осведомленный направит мои утверждения, исправив меня, где я неправ.
Преимущества закрытия:
- Инкапсулируйте переменные в локальную область с помощью внутренней функции. Анонимность функции незначительна.
Что я нашел полезным, так это провести базовое тестирование в отношении локальной/глобальной области:
<script type="text/javascript">
var global_text = "";
var global_count = 0;
var global_num1 = 10;
var global_num2 = 20;
var global_num3 = 30;
function outerFunc() {
var local_count = local_count || 0;
alert("global_num1: " + global_num1); // global_num1: undefined
var global_num1 = global_num1 || 0;
alert("global_num1: " + global_num1); // global_num1: 0
alert("global_num2: " + global_num2); // global_num2: 20
global_num2 = global_num2 || 0; // (notice) no definition with 'var'
alert("global_num2: " + global_num2); // global_num2: 20
global_num2 = 0;
alert("local_count: " + local_count); // local_count: 0
function output() {
global_num3++;
alert("local_count: " + local_count + "\n" +
"global_count: " + global_count + "\n" +
"global_text: " + global_text
);
local_count++;
}
local_count++;
global_count++;
return output;
}
var myFunc = outerFunc();
myFunc();
/* Outputs:
**********************
* local_count: 1
* global_count: 1
* global_text:
**********************/
global_text = "global";
myFunc();
/* Outputs:
**********************
* local_count: 2
* global_count: 1
* global_text: global
**********************/
var local_count = 100;
myFunc();
/* Outputs:
**********************
* local_count: 3
* global_count: 1
* global_text: global
**********************/
alert("global_num1: " + global_num1); // global_num1: 10
alert("global_num2: " + global_num2); // global_num2: 0
alert("global_num3: " + global_num3); // global_num3: 33
</script>
Интересные вещи, которые я извлек из этого:
Оповещения в externalFunc вызываются только один раз, когда вызов externalFunc назначается myFunc (myFunc = externalFunc()). Это назначение, кажется, держит externalFunc открытым, в том, что я хотел бы назвать постоянным состоянием.
Каждый раз, когда вызывается myFunc, выполняется возврат. В этом случае возврат является внутренней функцией.
Что действительно интересно, так это локализация, которая происходит при определении локальных переменных. Обратите внимание на разницу в первом предупреждении между global_num1 и global_num2: даже до того, как переменная пытается быть создана, global_num1 считается неопределенным, поскольку «var» использовалась для обозначения локальной переменной для этой функции. -- Об этом уже говорилось ранее, в порядке работы движка Javascript, просто приятно видеть, как это работает.
Глобальные переменные по-прежнему можно использовать, но локальные переменные переопределяют их. Обратите внимание, что перед третьим вызовом myFunc создается глобальная переменная с именем local_count, но это не влияет на внутреннюю функцию, которая имеет переменную с тем же именем. И наоборот, каждый вызов функции имеет возможность изменять глобальные переменные, как заметил global_var3.
Публикация мыслей. Несмотря на то, что код прост, он загроможден предупреждениями для вас, ребята, так что вы можете подключиться и работать.
Я знаю, что есть и другие примеры замыканий, многие из которых используют анонимные функции в сочетании с циклическими структурами, но я думаю, что это хорошо для курса 101 для начинающих, чтобы увидеть эффекты.
Единственное, что меня беспокоит, это негативное влияние замыканий на память. Поскольку он сохраняет среду функций открытой, он также хранит эти переменные в памяти, что может иметь или не иметь последствий для производительности, особенно в отношении обхода DOM и сборки мусора. Я также не уверен, какую роль это будет играть с точки зрения утечки памяти, и я не уверен, что замыкание можно удалить из памяти простым «удалить myFunc;».
Надеюсь, это поможет кому-то,
воль7рон