Pertimbangkan skrip berikut:
for (var i = 1; i <= 2; i++) { setTimeout(function () { alert(i) }, 100); }
Berbanding dengan nilai jangkaan 1 dan 2, skrip output 3 dua kali. Tingkah laku ini timbul disebabkan oleh sifat tak segerak bagi gelung peristiwa JavaScript.
Gelung peristiwa JavaScript memproses pelaksanaan kod dalam dua peringkat: tindanan segerak dan baris gilir tak segerak. Kod segerak dilaksanakan serta-merta dalam timbunan, manakala kod tak segerak, seperti setTimeouts, diletakkan dalam baris gilir untuk dilaksanakan kemudian.
Dalam skrip, setTimeout panggil balik fungsi menggunakan pembolehubah i. Walau bagaimanapun, i dikongsi antara semua lelaran gelung dan pada masa panggilan balik dilaksanakan, ia sentiasa merujuk kepada nilai akhir 2. Oleh itu, 3 dicetak kedua-dua kali.
Untuk memastikan nilai berturut-turut dicetak, cipta salinan i yang berbeza untuk setiap fungsi panggil balik. Ini boleh dicapai menggunakan penutupan fungsi, seperti yang ditunjukkan di bawah:
function doSetTimeout(i) { setTimeout(function () { alert(i); }, 100); } for (var i = 1; i <= 2; ++i) doSetTimeout(i);
Dalam skrip ini, fungsi doSetTimeout menangkap nilai i sebagai pembolehubah setempat untuk penutupannya, memastikan setiap fungsi panggil balik menggunakan yang betul nilai.
Atas ialah kandungan terperinci Mengapa Gelung JavaScript Ini Menghasilkan Keputusan Tidak Dijangka dengan `setTimeout`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!