[JavaScript] Fahami penutupan dalam beberapa saat

王林
Lepaskan: 2024-08-26 21:31:35
asal
895 orang telah melayarinya

[JavaScript] Understand closures in  seconds

Walaupun penutupan merupakan idea asas dalam JavaScript, pendatang baharu mungkin mendapati ia kabur dan mencabar untuk difahami. Secara khusus, definisi piawaian ECMA boleh mencabar untuk difahami tanpa sebarang pengalaman dunia sebenar. Akibatnya, kami akan memudahkan anda memahami dengan menggunakan kod sebenar daripada menjelaskan tanggapan penutupan dalam siaran ini.

1. Penutupan

function A(name){
    function B(){
       console.log(name);
    }
    return B;
}
var C = A("Closure");
C();//Closure
Salin selepas log masuk

Ini adalah penutupan yang paling mudah.

Sekarang kita tahu asasnya, mari kita semak secara ringkas bagaimana ini berbeza daripada fungsi biasa. Berikut ialah cara kod yang disebutkan di atas muncul apabila diterjemahkan ke dalam bahasa semula jadi:

  1. Tentukan fungsi biasa A, dengan nama argumen
  2. Tentukan fungsi biasa B dalam A, dan dalam B, rujuk nama pembolehubah luaran
  3. Kembalikan B dalam A
  4. Laksanakan A dan tetapkan hasilnya kepada pembolehubah C
  5. Jalankan C

Satu pernyataan boleh merangkumi lima operasi ini:

Fungsi B dalam fungsi A dan nama pembolehubah dirujuk oleh pembolehubah C di luar fungsi A.

Dengan sedikit pengubahsuaian, pernyataan ini mentakrifkan penutupan seperti berikut:

Apabila fungsi dalam dirujuk oleh pembolehubah di luar fungsi luar, penutupan terbentuk.

Oleh itu, melaksanakan lima operasi di atas mentakrifkan penutupan.

Penggunaan Penutupan

Sebelum kita memahami penggunaan penutupan, mari kita fahami mekanisme GC (Pengumpulan Sampah) JavaScript.

Dalam JavaScript, apabila objek tidak lagi dirujuk, ia akan dituntut semula oleh GC, jika tidak, ia akan terus disimpan dalam ingatan.

Dalam contoh di atas, B bergantung pada A kerana B ditakrifkan dalam A, dan A secara tidak langsung dirujuk oleh C kerana pembolehubah luaran C merujuk B.

Iaitu, A tidak akan dikumpul oleh GC dan akan terus disimpan dalam ingatan. Untuk membuktikan alasan ini, mari kita perbaiki sedikit contoh di atas.

function A(){
    var count = 0;
    function B(){
       count ++;
       console.log(count);
    }
    return B;
}
var C = A();
C();// 1
C();// 2
C();// 3
Salin selepas log masuk
  1. Jika kita memanggil var C = A();, A dilaksanakan, mewujudkan pembolehubah kiraan dan fungsi dalaman B. Oleh kerana A mengembalikan B, pembolehubah C sebenarnya mempunyai rujukan kepada B. Fungsi B kemudiannya boleh mengakses pembolehubah kira dalam A.
  2. Fungsi B boleh mengakses pembolehubah kiraan dalam A kerana B ialah penutupan. Ini kerana B ialah penutupan dan penutupan mengekalkan konteks di mana ia dicipta (cth., pembolehubah setempat).
  3. Apabila C() dipanggil, ia sebenarnya memanggil fungsi B. Setiap kali C() dipanggil, B menambah nilai kiraan dan memaparkan nilai itu pada konsol.
  4. Konteks pelaksanaan A tamat apabila B dicipta, tetapi pembolehubah tempatan A tidak dituntut semula selagi B merujuk pembolehubah setempatnya (seperti kiraan).
  5. Hanya apabila B tidak lagi dirujuk, pembolehubah kiraan dan pembolehubah tempatan lain dalam A akan dipulihkan. Dalam contoh ini, memandangkan C masih merujuk kepada B, nilai kiraan tidak dipulihkan, begitu juga konteks pelaksanaan A.

Mengapa kiraan tidak ditetapkan semula?

Mekanisme penutupan:

  • Penutupan mengekalkan keadaan kiraan dan memastikannya boleh diakses oleh fungsi dalaman B. Walaupun konteks pelaksanaan A ditamatkan, keadaan kiraan kekal dalam ingatan kerana B terus merujuk kepada keadaan ini.
  • Pada setiap panggilan ke B: Setiap panggilan ke C() sebenarnya adalah panggilan ke B(), yang menggunakan kiraan yang disimpan dalam penutupan dan tidak memulakannya semula.

Oleh itu, jika anda mentakrifkan beberapa pembolehubah dalam modul dan ingin menyimpan pembolehubah ini dalam ingatan tetapi tidak "mencemarkan" pembolehubah global, anda boleh mentakrifkan modul ini menggunakan penutupan.

Atas ialah kandungan terperinci [JavaScript] Fahami penutupan dalam beberapa saat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan