Реализация замыканий
Понять суть замыканий будет совсем несложно, если усвоить правило лек-
сической области видимости: во время выполнения функции используется
цепочка областей видимости, которая действовала в момент ее определе-
ния. Однако некоторые программисты испытывают сложности при освое-
нии замыканий, потому что не до конца понимают особенности реализа-
ции. Известно, думают они, что локальные переменные, объявленные во
внешней функции, прекращают свое существование после выхода из внеш-
ней функции, но тогда как вложенная функция может использовать цепоч-
ку областей видимости, которая больше не существует? Если вы задавали
себе такой вопрос, значит, у вас наверняка есть опыт работы с низкоуров-
невыми языками программирования, такими как C, и аппаратными архи-
тектурами, использующими стек: если локальные переменные размещать
на стеке, они действительно прекращают свое существование после завер-
шения функции.
Но вспомните определение цепочки областей видимости из раздела 3.10.3.
Там она описывалась как список объектов, а не стек. Каждый раз, когда
интерпретатор JavaScript вызывает функцию, он создает новый объект для
хранения локальных переменных этой функции, и этот объект добавляет-
ся в цепочку областей видимости. Когда функция возвращает управление,
этот объект удаляется из цепочки. Если в программе нет вложенных функ-
ций и нет ссылок на этот объект, он будет утилизирован сборщиком мусо-
ра. Если в программе имеются вложенные функции, тогда каждая из этих
функций будет владеть ссылкой на свою цепочку областей видимости, а це-
почка будет ссылаться на объекты с локальными переменными. Если объ-
екты вложенных функций существуют только в пределах своих внешних
функций, они сами будут утилизированы сборщиком мусора, а вместе
с ними будут утилизированы и объекты с локальными переменными, на
которые они ссылались. Но если функция определяет вложенную функ-
цию и возвращает ее или сохраняет в свойстве какого-либо объекта, то об-
разуется внешняя ссылка на вложенную функцию. Такой объект вложен-
ной функции не будет утилизирован сборщиком мусора, и точно так же не
будет утилизирован объект с локальными переменными, на который она
ссылается.
$arr = array('word1', 'word2', 'word3');
$n = count($arr);
for ($i = 1; $i <= $n; $i++) {
$pos[$i] = $i-1;
$c[$i] = 1;
$pr[$i] = 1;
}
$c[$n] = 0;
foreach($pos as $p)
echo $arr[$p],' ';
echo "<br>";
$i = 1;
while ($i < $n) {
$i = 1;
$x = 0;
while ($c[$i] == $n-$i+1) {
$pr[$i] = 1-$pr[$i];
$c[$i] = 1;
$x += $pr[$i];
$i++;
}
if ($i < $n) {
$k = $pr[$i] ? $c[$i]+$x : $n-$i+1-$c[$i]+$x;
$t = $pos[$k];
$pos[$k] = $pos[$k+1];
$pos[$k+1] = $t;
foreach($pos as $p)
echo $arr[$p],' ';
echo "<br>";
$c[$i]++;
}
}
word1 word2 word3
word2 word1 word3
word2 word3 word1
word3 word2 word1
word3 word1 word2
word1 word3 word2
else die;
curl_close($ch);