Zastosowanie leksykalnego otoczenia funkcji w JavaScript
Załóżmy, że mamy funkcję, która zwraca inną funkcję:
function test() {
return function() {
}
}
Jeśli funkcja nadrzędna ma jakieś zmienne, to te zmienne będą zawarte w leksykalnym otoczeniu zwracanej funkcji:
function test() {
let num = 1; // zmienna funkcji nadrzędnej
return function() {
// otoczenie leksykalne = {num: 1}
}
}
Napiszmy w kodzie naszej zwracanej funkcji
console.log, wypisujący wartość zmiennej
num:
function test() {
let num = 1;
return function() {
console.log(num);
}
}
Wywołajmy teraz funkcję nadrzędną
test i wynik jej działania zapiszmy
w zmiennej func:
function test() {
let num = 1;
return function() {
console.log(num);
}
}
let func = test();
Do zmiennej func zapisze się zwracana
funkcja. Wywołajmy naszą funkcję - swoim
wynikiem wypisze zawartość zmiennej
num:
function test() {
let num = 1;
return function() {
console.log(num);
}
}
let func = test();
func(); // wypisze 1
Jeśli natomiast po prostu spróbować wypisać zmienną
num poza funkcją - będzie niedostępna:
function test() {
let num = 1;
return function() {
console.log(num);
}
}
console.log(num); // zmienna num jest tu niedostępna
Jak widzisz, zmienna lokalna num
powiązała się z leksykalnym otoczeniem naszej
funkcji i teraz, wywołując w dowolnym miejscu kodu
tę funkcję, możemy uzyskać wartość
zmiennej num, nawet jeśli w miejscu
wywołania sama przez się ta zmienna jest niedostępna.
W rzeczywistości podobny wynik można
osiągnąć, robiąc zmienną num globalną:
function test() {
return function() {
console.log(num);
}
}
let num = 1; // zmienna globalna
let func = test();
func(); // wypisze 1
Tutaj jednak będzie istotna różnica:
w nowym wariancie zmienną num można
zmieniać poza funkcjami (ponieważ jest globalna),
a w starym - nie.
Określ, nie uruchamiając kodu, co zostanie wypisane w konsoli:
function test() {
let num1 = 1;
let num2 = 2;
return function() {
return num1 + num2;
}
}
let func = test();
console.log(func());
Określ, nie uruchamiając kodu, co zostanie wypisane w konsoli:
function test() {
let num1 = 1;
let num2 = 2;
return function() {
return num1 + num2;
}
}
console.log(test()());
Określ, nie uruchamiając kodu, co zostanie wypisane w konsoli:
function test() {
let num1 = 1;
return function() {
return num1 + num2;
}
}
let num2 = 2;
let func = test();
console.log(func());
Określ, nie uruchamiając kodu, co zostanie wypisane w konsoli:
function test() {
let num = 1;
return function() {
return num;
}
}
let num = 2;
let func = test();
console.log(func());