Soalan
Kod A
function fun(n,o){ console.log(o); return { fun:function(m){//[2] return fun(m,n);//[1] } } } var a=fun(0); a.fun(1); a.fun(2); a.fun(3); var b=fun(0).fun(1).fun(2).fun(3); var c=fun(0).fun(1); c.fun(2); c.fun(3);
Cari output program
Ini ialah soalan ujian penutup
Tukar kepada kod yang setara
Atribut keseronokan objek yang dikembalikan oleh pengembalian sepadan dengan objek fungsi yang baru dibuat Objek fungsi ini akan membentuk skop penutupan, membolehkannya mengakses pembolehubah n fungsi luar dan keseronokan fungsi luar gabungkan fungsi keseronokan dengan Atribut keseronokan keliru, kami mengubah suai kod di atas seperti berikut:
Kod B
function _fun_(n,o){ console.log(o); return { fun:function(m){ return _fun_(m,n); } } } var a=_fun_(0);//undefined a.fun(1);//0 a.fun(2);//0 a.fun(3);//0 var b=_fun_(0).fun(1).fun(2).fun(3); //undefined,0,1,2 var c=fun(0).fun(1);//undefined,0, c.fun(2);//1 c.fun(3); //1
Kemudian beberapa pelajar bertanya, mengapa ia boleh diubah seperti ini. Bagaimana anda boleh memastikan bahawa keseronokan di [1] bukan keseronokan di [2] di mana kod itu terletak Anda mesti tahu bahawa atribut menyeronokkan di sini? menunjuk ke objek fungsi
Di sini kita bercakap tentang skop leksikal JS Skop pembolehubah JS wujud dalam badan fungsi, iaitu, badan fungsi, dan skop pembolehubah ditentukan apabila definisi fungsi diisytiharkan, bukan apabila fungsi dijalankan.
Kod berikut
var name="global"; function foo(){ console.log(name); } function fooOuter1(){ var name="local"; foo(); } fooOuter1();//输出global 而不是local,并且和闭包没有任何关系 function fooOuter2(){ var name="local"; function foo(){ console.log(name); } foo(); } fooOuter2();//输出local 而不是global,在函数声明是name变量作用域就在其外层函数中,嗯嗯就是闭包~<br />
Buat skop penutupan
Selepas analisis leksikal, JS menentukan penutupan, iaitu penutupan fungsi tanpa nama yang sepadan dengan atribut keseronokan objek yang dikembalikan - pembolehubah dalaman n yang mengakses _func_ dalam persekitaran global dan fungsi luarnya; > Setiap kali _func_ dilaksanakan, maklumat skop pembolehubah dalam penutupan akan dihantar ke persekitaran pelaksanaan fungsi untuk digunakan apabila mendapatkan nilai pembolehubah apabila fungsi dilaksanakan
Output pelaksanaan
var a=_fun_(0);//undefined a.fun(1);//0 a.fun(2);//0 a.fun(3);//0
Jadi outputnya ialah 0, a.fun(2), a.fun(3) dan a.fun(1)
var b=_fun_(0).fun(1).fun(2).fun(3);
Kod yang setara:
var b=_fun_(0);
var b1=b.fun(1);
var b2=b1.fun(2);//[3]
var b3=b2.fun(3);//[4]
Dua ayat pertama adalah sama dengan keluaran di atas tidak ditentukan,0 Apabila [3] dipanggil, terdapat penutupan dalam objek b1, yang merujuk kepada fungsi _fun_ dan pembolehubah fungsi luar n=1. , jadi Panggilan fungsi yang dilakukan oleh fungsi tanpa nama ialah _fun_(2,1), hasil output ialah 1, dan objek baharu dikembalikan.
Apabila [4] dilaksanakan, objek b2 juga mempunyai penutupan, yang merujuk kepada fungsi _fun_ dan pembolehubah fungsi luar n=2 Apabila _fun_(3,2) dilaksanakan, hasil output ialah 2
var c=fun(0).fun(1);//undefined,0, c.fun(2);//1 c.fun(3); //1