Въпрос: Изглежда, че има много предимства на Closures, но какви са отрицателните (изтичане на памет? проблеми с обфускацията? увеличаване на честотната лента?)? Освен това, правилно ли разбирам Closures? И накрая, след като бъдат създадени затваряния, могат ли те да бъдат унищожени?
Четох малко за Javascript Closures. Надявам се някой малко по-запознат да насочи моите твърдения и да ме коригира там, където греша.
Предимства от затварянето:
- Капсулирайте променливите в локален обхват, като използвате вътрешна функция. Анонимността на функцията е незначителна.
Това, което намерих за полезно, е да направя някои основни тестове по отношение на локален/глобален обхват:
<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>
Интересни неща, които извадих от него:
Сигналите в outerFunc се извикват само веднъж, когато извикването на outerFunc е присвоено на myFunc (myFunc = outerFunc()). Това присвояване изглежда поддържа outerFunc отворен, в това, което бих искал да нарека постоянно състояние.
Всеки път, когато се извика myFunc, връщането се изпълнява. В този случай връщането е вътрешната функция.
Нещо наистина интересно е локализацията, която възниква при дефиниране на локални променливи. Забележете разликата в първото предупреждение между global_num1 и global_num2, дори преди променливата да се опита да бъде създадена, global_num1 се счита за недефиниран, тъй като 'var' е използван за обозначаване на локална променлива за тази функция. -- Това беше говорено преди, в реда на работа за двигателя на Javascript, просто е хубаво да видим това да работи.
Глобалните все още могат да се използват, но локалните променливи ще ги заменят. Забележете, че преди третото извикване на myFunc се създава глобална променлива, наречена local_count, но тя няма ефект върху вътрешната функция, която има променлива със същото име. Обратно, всяко извикване на функция има способността да променя глобалните променливи, както е отбелязано от global_var3.
Публикуване на мисли: Въпреки че кодът е ясен, той е претрупан от предупреждения за вас, момчета, така че можете да включите и да играете.
Знам, че има и други примери за затваряне, много от които използват анонимни функции в комбинация с циклични структури, но мисля, че това е добре за курс за 101 начинаещи, за да видите ефектите.
Единственото нещо, което ме тревожи, е отрицателното въздействие, което затварянията ще имат върху паметта. Тъй като поддържа функционалната среда отворена, тя също така запазва тези променливи, съхранени в паметта, което може/може да няма отражение върху производителността, особено по отношение на преминаването на DOM и събирането на боклука. Също така не съм сигурен каква роля ще играе това по отношение на изтичането на памет и не съм сигурен дали затварянето може да бъде премахнато от паметта чрез просто „изтриване на myFunc;.“
Надявам се това да помогне на някого,
vol7ron