Pengenalan ringkas kepada penutupan JavaScript

WBOY
Lepaskan: 2023-01-21 06:30:02
ke hadapan
1184 orang telah melayarinya

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.

Pengenalan ringkas kepada penutupan JavaScript

Apakah itu penutupan?

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:

  • Penutupan ialah fungsi (mengembalikan fungsi)
  • Fungsi yang dikembalikan menyimpan rujukan kepada pembolehubah luaran

Contoh mudah

function fn() {    let num = 1;    return function (n) {        return n + num
    }
}let rFn = fn()let newN = rFn(3) // 4
Salin selepas log masuk

Skop pembolehubah num berada dalam fungsi fn, tetapi fungsi rFn boleh mengakses pembolehubah num Ini bermakna fungsi penutupan boleh mengakses pembolehubah fungsi luaran.

Lihat penutupan daripada penyahpepijatan penyemak imbas dan penyahpepijatan VSCode Nodejs

  • Pelayar

Pengenalan ringkas kepada penutupan JavaScript

  • Kod VS bekerjasama dengan Node.js

Pengenalan ringkas kepada penutupan JavaScript

untuk melihat bahawa fn dalam Closure ialah fungsi penutupan, yang menyimpan pembolehubah num.

Penutupan klasik: mekanisme acara berbenang tunggal + masalah gelung dan penyelesaian

for (var i = 1; i  {    console.log(i);
  }, i * 1000);
}
Salin selepas log masuk
Salin selepas log masuk

Hasil keluaran semuanya 6, kenapa?

  • untuk gelung ialah tugas segerak
  • tugas tak segerak setTimeout

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.

Penyelesaian 1: Gunakan pernyataan let

for (var i = 1; i  {    console.log(i);
  }, i * 1000);
}
Salin selepas log masuk
Salin selepas log masuk

Penyelesaian 2: Fungsi laksana sendiri + penutupan

for (var i = 1; i  {    console.log(i);
  }, i * 1000)
  })(i)
}
Salin selepas log masuk

Penyelesaian 3: setTimeout melepasi parameter ketiga

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);
}
Salin selepas log masuk

Penutupan dan fungsi Currying

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
Salin selepas log masuk

参数 fungsi tambah menyimpan pembolehubah fungsi penutupan.

Kesan sebenar

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.

Senario penggunaan

  • Buat pembolehubah persendirian
  • Lanjutkan kitaran hayat pembolehubah

Fungsi Pendikit

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);
    }
}
Salin selepas log masuk

Fungsi anti goncang

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);
    }
}
Salin selepas log masuk

React. useCallback closure Masalah perangkap

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
Salin selepas log masuk
  • ChildWithMemo menggunakan memo untuk pengoptimuman dan
  • handleClickWithUseCallback menggunakan useCallback untuk pengoptimuman

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>
Salin selepas log masuk

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.

Isu prestasi

  • Jangan tentukan penutupan sewenang-wenangnya Setelah ditentukan, anda mesti mencari lokasi yang sesuai untuk pemusnahan. Oleh kerana pembolehubah penutupan disimpan dalam ingatan dan tidak akan dimusnahkan, ia menduduki jumlah memori yang tinggi.

Gunakan garis masa fungsi panel krom + panel profil

  1. Buka alatan pembangun dan pilih panel Garis Masa
  2. di bahagian atas Capture medan Semak Memori
  3. dan klik butang rekod di penjuru kiri sebelah atas.
  4. Lakukan pelbagai operasi pada halaman untuk mensimulasikan penggunaan pengguna.
  5. 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!

Label berkaitan:
sumber:juejin.im
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!