Bagaimanakah penutupan JavaScript berfungsi?
P粉494151941
2023-08-22 10:16:45
<p>Bagaimana untuk menerangkan penutupan kepada seseorang yang memahami konsep penutupan JavaScript (seperti fungsi, pembolehubah, dll.), tetapi tidak memahami penutupan itu sendiri? </p>
<p>Saya telah melihat contoh Skim yang diberikan di Wikipedia, tetapi malangnya ia tidak membantu. </p>
Dalam JavaScript, setiap fungsi mengekalkan pautan ke persekitaran leksikal luarannya. Persekitaran leksikal ialah peta semua nama (seperti pembolehubah, parameter) dan nilainya dalam skop.
Jadi, apabila anda melihat kata kunci
function
, kod di dalam fungsi itu boleh mengakses pembolehubah yang diisytiharkan di luar fungsi.Ini akan menghasilkan persekitaran leksikal
Persekitaran leksikal fungsi16
,因为函数bar
闭包了参数x
和变量tmp
,它们都存在于外部函数foo
.bar
与其与函数foo
dikaitkan bersama untuk membentuk penutup.tidak perlu kembali untuk membuat penutupan. Dengan pengisytiharan sahaja, setiap fungsi melampirkan persekitaran leksikalnya, membentuk penutup.
Fungsi di atas juga akan mengeluarkan 16 kerana
bar
中的代码仍然可以引用参数x
和变量tmp
, walaupun ia tidak lagi secara langsung dalam skop.Namun, sejak
tmp
仍然存在于bar
的闭包中,它可以被递增。每次调用bar
, semuanya akan bertambah.Contoh penutupan yang paling mudah ialah:
Apabila fungsi JavaScript dipanggil, konteks pelaksanaan baharu dicipta
ec
。除了函数参数和目标对象之外,该执行上下文还接收到调用执行上下文的词法环境的链接,这意味着在外部词法环境中声明的变量(在上面的示例中,即a
和b
)可以从ec
dan diakses di dalamnya.Setiap fungsi mencipta penutupan kerana setiap fungsi mempunyai pautan ke persekitaran leksikal luarannya.
Sila ambil perhatian bahawa apa yang kelihatan dalam penutupan ialah pembolehubah itu sendiri, bukan salinannya.
Penutupan ialah gandingan:
Persekitaran leksikal adalah sebahagian daripada setiap konteks pelaksanaan (bingkai tindanan) dan merupakan pemetaan antara pengecam (iaitu nama pembolehubah tempatan) dan nilai.
Setiap fungsi dalam JavaScript mengekalkan rujukan kepada persekitaran leksikal luarannya. Rujukan ini digunakan untuk mengkonfigurasi konteks pelaksanaan yang dibuat apabila fungsi dipanggil. Rujukan ini membolehkan kod di dalam fungsi untuk "melihat" pembolehubah yang diisytiharkan di luar fungsi, tanpa mengira bila dan di mana fungsi dipanggil.
Jika fungsi dipanggil daripada fungsi lain, satu siri rujukan kepada persekitaran leksikal luaran dicipta. Rantaian ini dipanggil rantai skop.
Dalam kod di bawah,
inner
与调用foo
时创建的执行上下文的词法环境形成了闭包,闭包包含变量secret
: