javascript - Parameter pertama setTimeout adalah untuk melaksanakan fungsi dengan segera, saya tidak dapat memahaminya
大家讲道理
大家讲道理 2017-07-05 10:56:26
0
9
1004

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

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

membalas semua(9)
给我你的怀抱

Dengan cara ini, semuanya dicetak sekali gus. . . Ia tidak dicetak setiap saat. . Adalah disyorkan untuk menulis seperti ini. .

for (var i = 0; i < 5; i++) {
  setTimeout((function(i) {
    return function() {
        console.log(i);
    }
  })(i), i * 1000);
}

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.

(fungsi(i) {

return function() {
    console.log(i);
}    

})(i)

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:

(function (i) {
      console.log(i);
})

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:

(function (i) {
    console.log(i);
})(i)

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).

迷茫

setTimeoutMemerlukan 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:

for (var i = 0; i < 5; i++) {
  setTimeout(function(i) {
    console.log(i);
  }, i * 1000);
}

Anda akan perasan bahawa pemasa sudah berfungsi, tetapi ia hanya mencetak satu setiap 1 saatundefined. Kerana apabila fungsi ini dilaksanakan, saya telah melompat keluar dari gelung dan tidak mempunyai nilai.

Jadi anda menukarnya kepada ini:

for (var i = 0; i < 5; i++) {
  setTimeout((function(i) {
    console.log(i);
  })(i), i * 1000);
}

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:

for (var i = 0; i < 5; i++) {
  setTimeout((function(i) {
    return function() {
        console.log(i);
    }
  })(i), i * 1000);
}

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:

var j = 0;
for (i = 0; i < 5; i++) {
  setTimeout(function() {
     console.log(j);
     j++;
  }, i * 1000);
}

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.

for (var i = 0; i < 5; i++) {
    setTimeout((function(i) {
        console.log(i);
    }).bind(this,i), i * 1000);
}
習慣沉默

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.

黄舟
(function(i) {
    console.log(i);
})(i)

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:

for (var i = 0; i < 5; i++) {
  var temp = (function(i) {
    console.log(i);
  })(i); 
  // temp 是 undefined 
  setTimeout(temp, i * 1000);
}

黄舟
  • 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

  • ?
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan