Rumah >hujung hadapan web >tutorial js >Pengenalan ringkas kepada penutupan JavaScript
Artikel ini membawakan anda pengetahuan yang berkaitan tentang JavaScript, yang terutamanya memperkenalkan isu yang berkaitan dengan penutupan JavaScript Terdapat banyak versi konsep penutupan, dan tempat yang berbeza mempunyai pendapat yang berbeza tentang penutupan. Mari kita lihat membantu semua orang.
Konsep penutupan mempunyai banyak versi, dan tempat yang berbeza mempunyai pendapat yang berbeza tentang penutupan
Wikipedia: Dalam sains komputer, penutupan (Bahasa Inggeris: Closure), Juga dikenali sebagai Lexical Closure atau penutupan fungsi, ia adalah teknik untuk melaksanakan pengikatan leksikal dalam bahasa pengaturcaraan yang menyokong fungsi kelas pertama.
MDN: Penutupan (penutupan) ialah fungsi dan keadaan persekitaran sekelilingnya yang digabungkan (persekitaran leksikal , persekitaran leksikal ).
Pemahaman peribadi:
function fn() { let num = 1; return function (n) { return n + num } }let rFn = fn()let newN = rFn(3) // 4
Skop pembolehubah num berada dalam fungsi fn, tetapi fungsi rFn boleh mengakses pembolehubah num Ini bermakna fungsi penutupan boleh mengakses pembolehubah fungsi luaran.
untuk melihat bahawa fn dalam Closure ialah fungsi penutupan, yang menyimpan pembolehubah num.
for (var i = 1; i { console.log(i); }, i * 1000); }
Hasil keluaran semuanya 6, kenapa?
untuk gelung sekali, tugas tak segerak setTimeout akan ditambahkan pada baris gilir tugas tak segerak penyemak imbas Selepas tugas segerak selesai, tugas baharu diambil daripada tugas tak segerak dan dilaksanakan dalam utas. Memandangkan setTimeout boleh mengakses pembolehubah luaran i, apabila tugas penyegerakan selesai, i telah menjadi 6, dan pembolehubah i yang boleh diakses dalam setTimeout adalah kesemuanya 6.
for (var i = 1; i { console.log(i); }, i * 1000); }
for (var i = 1; i { console.log(i); }, i * 1000) })(i) }
Parameter ketiga bermaksud: parameter tambahan, apabila pemasa tamat tempoh, ia akan dihantar sebagai parameter kepada fungsi yang akan dilaksanakan
for (var i = 1; i { console.log(j); }, 1000 * i, i); }
function add(num) { return function (y) { return num + y; }; };let incOneFn = add(1); let n = incOneFn(1); // 2let decOneFn = add(-1); let m = decOneFn(1); // 0
参数
fungsi tambah menyimpan pembolehubah fungsi penutupan.
Penutupan memainkan peranan yang sangat penting dalam pengaturcaraan berfungsi awal seperti lodash digunakan untuk mengimbangi kekurangan JavaScript, dan terdapat sejumlah besar senario penggunaan. untuk penutupan.
menghalang kelakuan menatal dan pelaksanaan fungsi yang berlebihan Ia mesti dikurangkan Fungsi pendikit menerima 函数
+ 时间
sebagai parameter, yang merupakan pembolehubah dalam penutupan versi setTimeout :
function throttle(fn, time=300){ var t = null; return function(){ if(t) return; t = setTimeout(() => { fn.call(this); t = null; }, time); } }
Perlaksanaan mudah fungsi anti goncang berdasarkan setTimeout
function debounce(fn,wait){ var timer = null; return function(){ if(timer !== null){ clearTimeout(timer); } timer = setTimeout(fn,wait); } }
Perihalan masalah: 父/子
Perhubungan komponen, komponen ibu bapa dan anak boleh menggunakan acara klik untuk mengubah suai data keadaan pada masa yang sama dan komponen anak mendapat atribut acara prop yang diluluskan, iaitu useCallback
dioptimumkan. Iaitu, fungsi yang dioptimumkan ini mempunyai perangkap penutupan, (nilai keadaan awal sentiasa disimpan)
import { useState, useCallback, memo } from "react";const ChildWithMemo = memo((props: any) => { return ( <div> <button>Child click</button> </div> ); });const Parent = () => { const [count, setCount] = useState(1); const handleClickWithUseCallback = useCallback(() => { console.log(count); }, []); // 注意这里是不能监听 count, 因为每次变化都会重新绑定,造成造成子组件重新渲染 return ( <div> <div>parent count : {count}</div> <button> setCount(count + 1)}>click</button> <childwithmemo></childwithmemo> </div> ); };export default Parent
Masalahnya ialah apabila subkomponen diklik, kiraan output ialah nilai awal (ditutup).
Penyelesaiannya ialah menggunakan useRef untuk menyimpan fungsi pembolehubah operasi:
import { useState, useCallback, memo, useRef } from "react";const ChildWithMemo = memo((props: any) => { console.log("rendered children") return ( <div> <button> props.countRef.current()}>Child click</button> </div> ); });const Parent = () => { const [count, setCount] = useState(1); const countRef = useRef<any>(null) countRef.current = () => { console.log(count); } return ( <div> <div>parent count : {count}</div> <button> setCount(count + 1)}>click</button> <childwithmemo></childwithmemo> </div> ); };export default Parent</any>
Sebagai tindak balas kepada masalah ini, React setelah meluluskan cadangan komuniti untuk menambah useEvent, tetapi kemudiannya Isu semantik useEvent telah ditinggalkan Sekarang, untuk pengoptimuman pemaparan, React menggunakan penyelesaian pengoptimuman kompilasi. Malah, masalah yang sama juga akan berlaku dalam useEffect Beri perhatian kepada perangkap penutupan apabila menggunakannya.
- Buka alatan pembangun dan pilih panel Garis Masa
- di bahagian atas
Capture
medan Semak Memori- dan klik butang rekod di penjuru kiri sebelah atas.
- Lakukan pelbagai operasi pada halaman untuk mensimulasikan penggunaan pengguna.
- Selepas tempoh masa, klik butang berhenti dalam kotak dialog, dan penggunaan memori dalam tempoh ini akan dipaparkan pada panel.
[Cadangan berkaitan: Tutorial video JavaScript, bahagian hadapan web]
Atas ialah kandungan terperinci Pengenalan ringkas kepada penutupan JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!