Closure sa TypeScript
Sa artikulong ito, ipapaliwanag natin ang tungkol sa mga closure sa TypeScript.
YouTube Video
Closure sa TypeScript
Ano ang Closure?
Ang closure ay tumutukoy sa kakayahang mapanatili ang mga sanggunian sa saklaw o kapaligiran kung saan tinukoy ang isang function, kahit tawagin ang function sa labas ng nasabing saklaw. Sa ibaba, ipapaliwanag ang mga closure kasama ang mga type annotations.
Sa madaling salita, ang closure ay pinagsasama ang isang function at ang kapaligiran ng variable kung saan ito itinukoy, kaya nagbibigay-daan upang ma-access ang kapaligiran kapag tinawag ang function.
Batayang Mekanismo ng Mga Closure
Sa TypeScript, kapag ang isang function ay tinukoy sa loob ng ibang function, napapatunayan na maaaring ma-access ng panloob na function ang mga variable ng panlabas na function. Narito ang isang pangunahing halimbawa ng closure na may mga type annotations.
1function outerFunction(): () => void {
2 let outerVariable: string = "I am from outer function";
3
4 function innerFunction(): void {
5 // The inner function accesses the variable of the outer function
6 console.log(outerVariable);
7 }
8
9 return innerFunction;
10}
11
12const closure: () => void = outerFunction();
13closure(); // "I am from outer function"
- Ang return type ng
outerFunction
ay() => void
, na nagpapahiwatig na nagsasauli ito ng isang function. - Ang uri ng
innerFunction
ay hayagang itinakda savoid
, na nagpapakita na wala itong isasauling halaga.
Mga Gamit at Bentahe ng Mga Closure
Encapsulation ng Data
Sa ibaba ay isang halimbawa ng closure na may type annotations para sa encapsulation ng data.
1function createCounter(): () => number {
2 let count: number = 0;
3
4 return function (): number {
5 count += 1;
6 return count;
7 };
8}
9
10const counter: () => number = createCounter();
11console.log(counter()); // 1
12console.log(counter()); // 2
13console.log(counter()); // 3
- Ang function na
createCounter
ay nagsasauli ng isang function na may uri na() => number
. - Ang variable na
count
ay tinukoy bilangnumber
na uri at binabago sa loob ng closure.
Mas Mataas na Antas ng Mga Function
Ang mga closure ay kapaki-pakinabang kapag gumagawa ng mas mataas na antas ng mga function. Sa ibaba ay isang halimbawa ng mas mataas na antas ng function na may malinaw na type annotations.
1function createMultiplier(multiplier: number): (value: number) => number {
2 return function (value: number): number {
3 return value * multiplier;
4 };
5}
6
7const double: (value: number) => number = createMultiplier(2);
8console.log(double(5)); // 10
9
10const triple: (value: number) => number = createMultiplier(3);
11console.log(triple(5)); // 15
- Ang
createMultiplier
ay tumatanggap ng argumento na may uri nanumber
at nagsasauli ng isang function na may uri na(value: number) => number
. - Ang panloob na function ay tumatanggap din ng
value
bilang uri nanumber
at isasauli ang resulta bilang uri nanumber
.
Halimbawa ng Pagpapatupad ng Mga Closure sa TypeScript
Ipatupad ang isang range-bound na counter bilang isang closure na may karagdagang mga type annotations.
1function rangeCounter(min: number, max: number): () => number | string {
2 let count: number = min;
3
4 return function (): number | string {
5 if (count <= max) {
6 return count++;
7 } else {
8 return `Count has exceeded the maximum value: ${max}`;
9 }
10 };
11}
12
13const counter: () => number | string = rangeCounter(1, 5);
14
15console.log(counter()); // 1
16console.log(counter()); // 2
17console.log(counter()); // 3
18console.log(counter()); // 4
19console.log(counter()); // 5
20console.log(counter()); // "Count has exceeded the maximum value: 5"
- Ang function na
rangeCounter
ay nagsasauli ng isang function na nagsasauli ng alinman sanumber
ostring
. - Sa panloob na function, kung ang
count
ay lumampas samax
, nagbibigay ito ng mensaheng uri ngstring
; kung hindi, nagbibigay ito ng uri ngnumber
.
Mga Pag-iingat Kapag Gumagamit ng Closures
Posibleng Memory Leaks mula sa Closures
Maaaring panatilihin ng closures ang mga variable mula sa panlabas na saklaw, na maaaring magdulot paminsan-minsan ng memory leaks. Ang mga hindi kailangang closures ay kailangang tahasang alisin mula sa memorya.
1function createLeak(): () => void {
2 // Large array consuming significant memory
3 const largeArray: string[] = new Array(1000000).fill("leak");
4
5 // Closure capturing `largeArray`
6 return function (): void {
7 console.log(largeArray[0]); // Using the captured array
8 };
9}
10
11// Create a closure that holds a reference to the large array
12let leakyFunction = createLeak();
13
14// The large array is not released as `leakyFunction` still references it
15
16// When the object is no longer needed
17leakyFunction = null; // Explicitly remove the reference
- Sa code na ito, ang
largeArray
na nilikha sa loob ngcreateLeak
ay inaasahang maaalis kapag ito ay lumabas ng saklaw, ngunit hindi ito nangyayari dahil kinukuha ng closure anglargeArray
. Hangga't umiiral angleakyFunction
, ang hindi kailangang memoryang ito ay magpapatuloy na mapanatili. - Kapag ang isang object o variable ay hindi na kailangan, ang pag-set sa reference nito sa
null
ay magpapahintulot sa garbage collector na makita ito at palayain ang memorya.
Maling Paggamit ng Closures sa Mga Loops
Kapag lumilikha ng closures sa loob ng isang loop, maaaring magkaroon ng mga isyu sa pag-refer sa parehong variable. Ang sumusunod na halimbawa ay nagpapakita ng isang kaso kung saan ang variable na i
ay hindi gumagana nang maayos.
1for (var i: number = 0; i < 3; i++) {
2 setTimeout((): void => {
3 console.log(i);
4 }, 1000);
5}
6// Output: 3, 3, 3
Hindi nagbibigay ang code na ito ng nais na resulta dahil ang i
ay tumutukoy sa halagang 3 sa dulo ng loop. Upang ayusin ito, gamitin ang let
upang paghiwalayin ang saklaw o gumamit ng isang agad na tinawag na function.
1for (let i: number = 0; i < 3; i++) {
2 setTimeout((): void => {
3 console.log(i);
4 }, 1000);
5}
6// Output: 0, 1, 2
Sa pamamagitan ng paggamit ng let
, ang saklaw ng i
ay hiwalay para sa bawat pag-ulit ng loop, nagbibigay ng inaasahang mga resulta.
Buod
Sa TypeScript, ang closures ay maaaring humantong sa mas ligtas at mas mahuhulaang code sa pamamagitan ng paggamit sa type system. Ang tamang paggamit ng closures ay nagpapahintulot sa pag-encapsulate ng data at nababaluktot na disenyo ng mas mataas na antas ng mga function. Dagdag pa rito, kailangang mag-ingat sa pamamahala ng memorya at mga hindi sinasadyang pag-refer sa saklaw kapag gumagamit ng closures.
Maaari mong sundan ang artikulo sa itaas gamit ang Visual Studio Code sa aming YouTube channel. Paki-check din ang aming YouTube channel.