Poznajemy closures, czyli domknięcia, i ich największą zaletę, czyli zastosowanie w rekurencji. Już z nich korzystaliśmy. Do dzieła.
Zobaczmy na tę funkcję:
Document.prototype.myGetElementById = function(id) {
var result = null;
function traverse(node) {
if(node == null)
return;
if(node.id === id) {
result = node;
return;
}
for(var child of node.children)
traverse(child);
}
traverse(this.documentElement);
return result;
}
Zmienna result wykorzystuje domknięcie. Funkcja travese ma do niech dostęp. Oczywiście w języku PHP trzeba by było to dookreślić:
function pseudoCode($id){
$result = null;
function traverse($node) use ($result) {
// function body
}
//(...)
}
Ok, ale po co nam dostęp do result? Można po prostu zwrócić result. Cóż, można. W przypadku jednego elementu, można.
Zobaczmy jednak na tę funkcję:
Document.prototype.myGetElementsByClassname = function(classname) {
var result = [];
function traverse(node) {
if(node == null)
return;
if(node.classList.contains(classname))
result.push(node);
for(var child of node.children)
traverse(child);
}
traverse(this.documentElement);
return result;
}
Tutaj mamy tablicę. Funkcja rekurencyjna może spokojnie do tej tablicy dopisywać, a funkcja główna tę tablicę zwrócić. Nie trzeba tablicy przekazywać rekurencyjnie w dół a potem w górę mnożąc argumenty funkcji, mnożąc space complexity oraz komplikując logikę.
Domknięcia to bardzo potężny mechanizm.