Parameter pertama setTimeout adalah untuk melaksanakan fungsi dengan segera, saya tidak dapat memahaminya
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}
Walaupun hasilnya adalah untuk mengeluarkan 0,1,2,3,4 serta-merta, saya tidak tahu mengapa
Dengan cara ini, semuanya dicetak sekali gus. . . Ia tidak dicetak setiap saat. . Adalah disyorkan untuk menulis seperti ini. .
Biar saya jelaskan mengapa 0, 1, 2, 3, 4 boleh diperolehi
Terdapat banyak artikel tentang pra-tafsiran JS di Internet Fungsi tidak akan dilaksanakan apabila memasuki peringkat konteks pelaksanaan anda mengisytiharkan fungsi ini, ia tidak akan dilaksanakan selagi ia tidak dipanggil Hanya rujukan kepada fungsi ini akan disimpan dalam konteks Ia boleh dilihat bahawa fungsi ini disimpan dalam memori ia dipanggil. Biar saya bercakap tentang diri saya memahami, sila nyatakan jika ada sesuatu yang salah.
Jika fungsi tidak dilaksanakan dengan segera:
Anda sebenarnya mentakrifkan 5 pemasa dalam gelung for, tetapi js adalah satu-benang, dan lima fungsi ini akan dimasukkan ke dalam baris gilir untuk menunggu pelaksanaan Berikut adalah contoh yang mungkin tidak sesuai. , anda menyimpan lima fungsi function() {console.log(i);} sebagai rentetan dalam ingatan, dan tidak akan ada pergerakan sehingga lima panggilan fungsi dilaksanakan (yang merupakan parameter kedua setTimeout Apabila masa sudah selesai), fungsi akan mula dilaksanakan, kerana terdapat i dalam fungsi Pada masa ini, i akan dicari melalui rantai skop, dan akhirnya i ditemui dalam skop luar, tetapi pada masa ini. untuk gelung telah pun dilaksanakan, i telah menjadi 4, jadi lima 4 akan dicetak
Jika terdapat fungsi pelaksanaan segera (seperti yang saya tulis di atas):
Anda sebenarnya bersamaan dengan menentukan 5 pemasa dalam. gelung untuk, Tetapi js adalah satu-benang, dan lima fungsi ini akan diletakkan dalam baris gilir menunggu pelaksanaan.
Tetapi kerana fungsi di luar dilaksanakan serta-merta, ia akan dilaksanakan serta-merta, dan i diluluskan. Apabila lima fungsi ini dilaksanakan, i dicari ke atas, dan i ditemui dalam skop fungsi yang dipanggil dengan segera cetak 0, 1, 2, 3, 4.
Anda lihat dahulu kurungan yang melampirkan keseluruhan fungsi
Iaitu:
Pemahaman perenggan ini adalah untuk membungkus diri anda ke dalam satu pakej, keseluruhan, dan keseluruhan ini adalah fungsi
Jadi bagaimana untuk memanggil fungsi seterusnya? Adakah nama fungsi () seperti ini? Tambah kurungan selepas nama fungsi, dan anda boleh menghantar parameter ke dalamnya
Jadi secara semula jadi, inilah yang berlaku:
Panggilan jenis ini adalah untuk menulis fungsi, membungkusnya dengan (), mengikutinya dengan (), menulis parameter di dalamnya, dan melaksanakannya secara langsung
Seperti yang dinyatakan di atas, ia dicetak serta-merta, tetapi setTimeout anda tidak mempunyai kesan sama sekali.
Alasannya ialah tiada nilai pulangan selepas fungsi pelaksanaan segera dilaksanakan, jadi ia bersamaan dengan setTimeout(undefined, i*1000).
setTimeout
Memerlukan parameter pertama untuk menjadi fungsi, supaya selepas masa yang ditentukan oleh parameter kedua tamat, fungsi yang ditakrifkan oleh parameter pertama akan dilaksanakan.Apabila anda menulis:
Anda akan perasan bahawa pemasa sudah berfungsi, tetapi ia hanya mencetak satu setiap 1 saat
undefined
. Kerana apabila fungsi ini dilaksanakan, saya telah melompat keluar dari gelung dan tidak mempunyai nilai.Jadi anda menukarnya kepada ini:
Tetapi dalam kes ini, parameter pertama bukan fungsi, tetapi ungkapan, yang bermaksud fungsi itu akan dilaksanakan serta-merta. Ia tidak akan menunggu sehingga pemasa berkuat kuasa, tetapi akan dilaksanakan sebaik sahaja ia ditemui , jadi bentuk ungkapan adalah untuk terus menaip 0, 1, 2, 3, 4.
Tukar kepada ini mengikut kenyataan di atas:
Walaupun parameter pertama ialah ungkapan, ia masih akan dilaksanakan dengan serta-merta Walau bagaimanapun, hasil daripada pelaksanaan ungkapan ini bukan untuk mengeluarkan nilai, tetapi untuk mengembalikan fungsi Ini memenuhi keperluan setTimeout bahawa parameter pertama adalah fungsi , dan memberikan Parameter input yang betul ditetapkan, jadi hasil yang betul akan dikeluarkan setiap 1 saat.
Namun, demi kerjasama pasukan, saya secara amnya tidak mengesyorkan menulis seperti ini, saya cadangkan anda mengikuti kaedah penulisan standard setTimeout dan menulisnya seperti ini:
Ini sekurang-kurangnya akan memudahkan ahli kumpulan lain membaca dan memahami.
Kerana ia adalah fungsi yang dilaksanakan serta merta, sudah tentu ia dikeluarkan serta merta
Untuk isu skop fungsi, ubah sahaja perkara ini.
Jika fungsi tidak dilaksanakan serta-merta, lima 5s akan dicetak, dan ia akan dicetak setiap satu saat, kerana fungsi dalam setTimeout tidak akan dilaksanakan sehingga gelung selesai Pada masa ini, pembolehubah global i ialah 5. Menggunakan fungsi pelaksanaan serta-merta, setiap i dalam gelung akan diperolehi kesan penutupan ini kini adalah pembolehubah tempatan dan wujud dalam fungsi ini adalah berbeza setiap kali ia dilaksanakan.
Diisytiharkan akan dilaksanakan dengan segera. Ini adalah
0 1 2 3 4
Walau bagaimanapun, ini tidak mempunyai nilai pulangan, jadi lalainya ialah
undefined
Jadi kod anda boleh dianggap seperti ini:
Fahami prinsip, penutupan, tindanan, baris gilir acara, penyegerakan, tak segerak
Terbalikkan idea: alih keluar parameter yang saya masukkan dan lihat sama ada ia boleh mencetak seperti biasa. Jika tidak, analisa mengapa
Bolehkah anda menukar kaedah penulisan untuk mencapai kesan yang sama seperti di atas. Analisa kenapa
Selepas melengkapkan perkara di atas, anda akan tahu sebab, proses dan hasilnya