Apakah fungsi pendikit?
Pendikitan fungsi bermaksud kita tidak mahu fungsi dipanggil secara berterusan dalam tempoh yang singkat Contohnya, perkara yang paling biasa kita lakukan ialah apabila tetingkap dizum, kita sering melakukan beberapa fungsi operasi yang lain. seperti menghantar permintaan ajax Tunggu, kemudian apabila tetingkap dizum, adalah mungkin untuk menghantar berbilang permintaan secara berterusan, yang bukan apa yang kita mahu, atau kesan penukaran tab biasa kami untuk menggerakkan tetikus masuk dan keluar, kadang-kadang secara berterusan dan sangat. dengan cepat Kadangkala, akan ada kesan kelipan Pada masa ini, kita boleh menggunakan pendikit fungsi untuk beroperasi. Seperti yang kita semua tahu, operasi DOM akan sangat memakan atau menjejaskan prestasi Jika sebilangan besar operasi DOM terikat kepada elemen apabila tetingkap dizum, ia akan menyebabkan sejumlah besar pengiraan berterusan Sebagai contoh, di bawah IE, terlalu banyak Operasi DOM akan berlaku Operasi ini akan menjejaskan prestasi penyemak imbas, malah menyebabkan penyemak imbas ranap dalam kes yang teruk. Pada masa ini kita boleh menggunakan pendikit fungsi untuk mengoptimumkan kod~
Prinsip asas pendikitan fungsi:
Gunakan pemasa untuk menangguhkan pelaksanaan fungsi dahulu Contohnya, gunakan fungsi setTomeout() untuk menangguhkan pelaksanaan fungsi untuk satu tempoh masa Jika peristiwa lain dicetuskan dalam tempoh masa ini, kita boleh gunakan kaedah clearTimeout() Untuk mengosongkan pemasa, setTimeout() pemasa baharu untuk menangguhkan pelaksanaan buat seketika.
Baru-baru ini, pasukan sedang sibuk dengan projek Terdapat halaman seperti ini, yang dibangunkan dalam mod tradisional (mengeluh tentang mengapa ia tidak menggunakan React, dan prestasinya adalah). agak lemah, terutamanya apabila anda mengezum masuk dan keluar dari tetingkap, ia adalah mengerikan Sesuatu telah berlaku, berlaku ketinggalan, atau pelayar ranap. kenapa?
Memandangkan halaman ini mempunyai banyak operasi DOM, pelaksanaan fungsi akan dicetuskan setiap bingkai apabila tetingkap dizum, dan operasi DOM akan diulang secara berterusan, yang sangat mahal untuk penyemak imbas. Memandangkan penyemak imbas akan mengira semula DOM apabila tetingkap dizum, mengapa kita tidak boleh menangguhkan pengiraan DOM dan membiarkan tetingkap berhenti mengezum sebelum mengiranya semula Ini akan menjimatkan overhed penyemak imbas dan mencapai kesan pengoptimuman?
Persediaan ilmu
1. setTimeout(code,millisec) sudah tentu merupakan protagonis artikel ini.
Kaedah setTimeout() digunakan untuk memanggil fungsi atau ungkapan yang dikira selepas bilangan milisaat yang ditentukan.
kod diperlukan. Rentetan kod JavaScript yang akan dilaksanakan selepas fungsi yang akan dipanggil.
millisec diperlukan. Bilangan milisaat untuk menunggu sebelum melaksanakan kod.
Petua: setTimeout() hanya melaksanakan kod sekali. Jika anda ingin memanggilnya beberapa kali, gunakan setInterval() atau minta kod itu sendiri memanggil setTimeout() sekali lagi.
Digunakan secara meluas dalam pemasa, karusel, kesan animasi, penatalan automatik, dsb.
2. clearTimeout(id_of_setTimeout)
Parameter id_of_settimeout ialah nilai ID yang dikembalikan oleh setTimeout(). Nilai ini mengenal pasti blok kod pelaksanaan tertunda untuk dibatalkan.
3. seronok.apply(thisArg[, argsArray])
Kaedah apply() memanggil fungsi dengan menyatakan nilai dan parameter ini (parameter wujud dalam bentuk tatasusunan atau objek seperti tatasusunan)
Sintaks fungsi ini hampir sama dengan kaedah panggilan() Satu-satunya perbezaan ialah kaedah panggilan() menerima senarai parameter, manakala apply() menerima tatasusunan (atau objek seperti tatasusunan) yang mengandungi berbilang. parameter.
Parameter
Arg ini
Nilai ini ditentukan apabila fungsi keseronokan sedang berjalan. Perlu diingatkan bahawa nilai ini yang dinyatakan tidak semestinya nilai ini sebenar apabila fungsi itu dilaksanakan Jika fungsi itu dalam mod tidak ketat, ia akan secara automatik menunjuk ke objek global (objek tetingkap dalam pelayar) apabila ia berada. dinyatakan sebagai null atau undefined ), dan ini yang nilainya ialah nilai primitif (nombor, rentetan, nilai Boolean) akan menunjuk ke objek pembalut automatik bagi nilai primitif.
argsArray
Suatu tatasusunan atau objek seperti tatasusunan, elemen tatasusunan yang akan dihantar sebagai parameter berasingan kepada fungsi yang menyeronokkan. Jika nilai parameter ini adalah batal atau tidak ditentukan, ini bermakna tiada parameter perlu dihantar. Bermula dari ECMAScript 5, objek seperti tatasusunan tersedia.
Apabila memanggil fungsi sedia ada, anda boleh menentukan objek ini untuknya. ini merujuk kepada objek semasa, iaitu objek yang memanggil fungsi ini. Menggunakan apply, anda boleh menulis kaedah sekali dan kemudian mewarisinya dalam objek lain, tanpa perlu menulis kaedah berulang kali dalam objek baharu.
4. fun.call(thisArg[, arg1[, arg2[, ...]]])
Kaedah ini memanggil fungsi atau kaedah menggunakan nilai ini yang ditentukan dan beberapa nilai parameter yang ditentukan.
Parameter
arg ini
Nilai ini ditentukan apabila fungsi keseronokan sedang berjalan. Perlu diingatkan bahawa nilai ini yang dinyatakan tidak semestinya nilai ini sebenar apabila fungsi dilaksanakan Jika fungsi dalam mod tidak ketat, nilai ini yang dinyatakan sebagai null dan undefined akan secara automatik menunjuk ke objek global (dalam. penyemak imbas, ini adalah objek tetingkap), dan ini yang nilainya ialah nilai primitif (nombor, rentetan, nilai Boolean) akan menunjuk ke objek pembalut automatik bagi nilai primitif.
arg1, arg2, ...
Senarai parameter yang ditentukan.
Apabila memanggil fungsi, anda boleh menetapkan objek ini yang berbeza. ini merujuk kepada objek semasa, parameter pertama kaedah panggilan. Melalui kaedah panggilan, anda boleh meminjam kaedah pada satu objek daripada objek lain, seperti Object.prototype.toString.call([]), iaitu kaedah peminjaman objek Array pada objek Objek.
Fungsi:
Gunakan kaedah panggilan untuk memanggil pembina induk
Gunakan kaedah panggilan untuk memanggil fungsi tanpa nama
Gunakan kaedah panggilan untuk memanggil fungsi tanpa nama dan nyatakan konteks 'ini'
Penyimpangan di sini:
apply sangat serupa dengan call(), perbezaannya terletak pada cara parameter disediakan. apply menggunakan tatasusunan argumen dan bukannya senarai argumen. apply boleh menggunakan literal tatasusunan, seperti fun.apply(ini, ['makan', 'pisang']), atau objek tatasusunan, seperti fun.apply(ini, Array baharu('makan', 'pisang' )). Anda juga boleh menggunakan objek argumen sebagai parameter argsArray. argumen ialah pembolehubah tempatan bagi sesuatu fungsi. Ia boleh digunakan sebagai mana-mana parameter yang tidak ditentukan bagi objek yang dipanggil. Dengan cara ini, anda tidak perlu mengetahui semua parameter objek yang dipanggil apabila menggunakan fungsi gunakan. Anda boleh menggunakan argumen untuk menghantar semua argumen kepada objek yang dipanggil. Objek yang dipanggil kemudiannya bertanggungjawab untuk memproses parameter ini.
Bermula dari ECMAScript versi 5, anda boleh menggunakan sebarang jenis objek seperti tatasusunan, iaitu, selagi ia mempunyai sifat panjang dan sifat integer dalam julat [0...panjang). Sebagai contoh, anda kini boleh menggunakan NodeList atau objek yang ditakrifkan sendiri serupa dengan {'length': 2, '0': 'eat', '1': 'bananas'}.
Perbezaan antara kaedah panggilan dan gunakan ialah bermula dari parameter kedua, parameter kaedah panggilan akan dihantar kepada kaedah yang dipinjam sebagai parameter, manakala apply terus meletakkan parameter ini ke dalam tatasusunan dan kemudian menghantarnya, dan akhirnya senarai parameter kaedah yang dipinjam Ia adalah sama.
Senario aplikasi: panggilan boleh digunakan apabila parameter jelas, dan gunakan boleh digunakan untuk menggabungkan argumen apabila parameter tidak jelas
Sekarang berikan contoh
Seperti yang kita semua tahu, onscolll, onresize, dsb. adalah sangat intensif prestasi, dan nombor dicetak apabila tetingkap dizum.
var count = ; window.onresize = function () { count++; console.log(count); }
Tarik balik dan tarik semula saiz tetingkap penyemak imbas dalam penyemak imbas Chrome, cetak seperti berikut
Ini jelas bukan yang kita mahukan Jika kita beralih kepada permintaan ajax, tetingkap akan dizum sekali dan berbilang permintaan ajax akan dicetuskan berturut-turut Mari cuba gunakan pendikitan fungsi. ) pemasa,
Kaedah pembungkusan pertama
var count = ; function oCount() { count++; console.log(count); } window.onresize = function () { delayFun(oCount) }; function delayFun(method, thisArg) { clearTimeout(method.props); method.props = setTimeout(function () { method.call(thisArg) }, ) }
Kaedah pembungkusan kedua
Bina penutupan dan gunakan penutupan untuk membentuk skop peribadi untuk menyimpan pemasa Pemasa diperkenalkan dengan lulus parameter.
var count = ; function oCount() { count++; console.log(count); } var funs= delayFun(oCount,); window.onresize = function () { funs() }; function delayFun(func, wait) { var timer = null; return function () { var context = this, args = arguments; clearTimeout(timer); timer = setTimeout(function () { func.apply(context, args); }, wait) }; }
Optimumkan kaedah kedua dan prestasi akan menjadi lebih baik
Ini mengembalikan fungsi yang tidak akan dilaksanakan jika ia dipanggil tanpa gangguan. Fungsi ini tidak akan dilaksanakan sehingga ia dipanggil semula N milisaat selepas ia berhenti dipanggil. Jika parameter 'segera' diluluskan, fungsi akan dijadualkan ke baris gilir pelaksanaan serta-merta tanpa berlengah-lengah.
function delayFun (func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; // 用法 var myEfficientFn = delayFun (function() { // 所有繁重的操作 }, ); window.addEventListener('resize', myEfficientFn);
Fungsi ini tidak membenarkan fungsi panggil balik dilaksanakan lebih daripada sekali dalam masa yang ditetapkan. Fungsi ini amat penting apabila menetapkan fungsi panggil balik kepada acara yang akan dicetuskan dengan kerap.
setTimeout sangat berkuasa, bolehkah kita menggunakannya secara meluas dalam projek?
Saya secara peribadi tidak mengesyorkannya Dalam perniagaan kami, pada dasarnya dilarang menggunakan setTimeout dalam logik perniagaan, kerana banyak kaedah penggunaan yang saya lihat adalah masalah yang mudah diselesaikan, dan setTimeout digunakan sebagai hack.
Sebagai contoh, apabila tika belum dimulakan, kami menggunakan tika ini Penyelesaian yang salah ialah menambah setTimeout apabila menggunakan tika itu untuk memastikan tika itu dimulakan.
Kenapa salah? Ini sebenarnya kaedah menggunakan hacks
Yang pertama ialah meletakkan perangkap dan mengganggu kitaran hayat modul
Yang kedua ialah apabila masalah berlaku, setTimeout sebenarnya sukar untuk dinyahpepijat.
Saya rasa cara yang betul untuk menggunakannya ialah melihat kitaran hayat (sila rujuk "Mengenai Kitaran Hayat Perisian") dan sebutkan instantiasi sebelum digunakan.
Mengenai penggunaan bijak setTimeout dalam JS dan pendikitan fungsi bahagian hadapan, editor akan memperkenalkannya kepada anda di sini, saya harap ia akan membantu anda!