Rumah  >  Soal Jawab  >  teks badan

javascript - Apakah kegunaan penutupan dalam pembangunan praktikal?

Selepas menonton penjelasan fungsi penutupan dalam video, saya masih tidak faham Sebagai contoh, kod dalam tangkapan skrin boleh dilaksanakan dengan menambah parameter garis laluan pada fungsi cmp.

Siapa yang boleh memberi contoh yang lebih baik untuk menggambarkan peranan penutupan?

PHPzPHPz2713 hari yang lalu888

membalas semua(9)saya akan balas

  • 过去多啦不再A梦

    过去多啦不再A梦2017-05-16 13:37:00

    Melanjutkan kitaran hayat pembolehubah tempatan dan merangkum pembolehubah persendirian

    2. 延续局部变量的寿命
    img 对象经常用于进行数据上报,如下所示:
    var report = function( src ){
        var img = new Image();
        img.src = src;
    };
    report( 'http://xxx.com/getUserInfo' );
    但是通过查询后台的记录我们得知,因为一些低版本浏览器的实现存在 bug,在这些浏览器
    下使用 report 函数进行数据上报会丢失 30%左右的数据,也就是说, report 函数并不是每一次
    都成功发起了 HTTP 请求。丢失数据的原因是 img 是 report 函数中的局部变量,当 report 函数的
    调用结束后, img 局部变量随即被销毁,而此时或许还没来得及发出 HTTP 请求,所以此次请求
    就会丢失掉。
    现在我们把 img 变量用闭包封闭起来,便能解决请求丢失的问题:
    var report = (function(){
        var imgs = [];
        return function( src ){
            var img = new Image();
            imgs.push( img );
            img.src = src;
        }
    })();

    balas
    0
  • 伊谢尔伦

    伊谢尔伦2017-05-16 13:37:00

    Simpan pembolehubah Selalunya saya menggunakannya untuk menggantikan pembolehubah global untuk mengelakkan pencemaran berubah

    balas
    0
  • 巴扎黑

    巴扎黑2017-05-16 13:37:00

    Masalah yang diselesaikan dengan penutupan: Berdasarkan JS词法作用域规则,其访问是一直向上查找作用域,直到全局作用域。而想直接访问某个作用域可通过闭包解决。

    function foo(){
    var a = 1;
    function bar(){
        console.log(a);
    }
    return bar;
    }
    var baz = foo();
    baz();

    bar词法作用域可以访问foo内部作用域,foo执行后返回bar,最后赋值给baz,可以获取并访问foo内部作用域,只是标识符不同而已。
    该代码就使用了闭包,可以说写JS代码处处可见闭包,使用闭包还有一个好处就是引用的作用域不会被垃圾回收处理,当然不合理的使用会耗内存

    闭包用来增加变量(能访问某作用域,自然能加变量)或者延长其生命周期(作用域被引用,自然会延长)

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

    第一个循环是声明了几个函数,共享全局i变量(变量和函数声明都提升了)。
    第二个循环是定义了几个立即执行函数,又传递了i值,故每个iperaturan skop leksikal
    JS, aksesnya adalah untuk mencari skop ke atas sehingga

    skop global

    . Jika anda ingin mengakses skop tertentu secara langsung, anda boleh menggunakan penutupan. rrreee Skop leksikal bar boleh mengakses skop dalaman foo Selepas foo dilaksanakan, ia mengembalikan bar dan akhirnya memberikannya kepada < code>baz, boleh mendapatkan dan mengakses skop dalaman foo, tetapi pengecam adalah berbeza.

    Kod ini menggunakan penutupan Boleh dikatakan penutupan boleh dilihat di mana-mana apabila menulis kod JS Satu lagi kelebihan menggunakan penutupan ialah skop yang dirujuk tidak akan dikumpul, yang sudah tentu tidak munasabah. Menggunakannya akan memakan memori

    . Penutupan digunakan untuk

    menambah pembolehubah 🎜 (jika anda boleh mengakses skop tertentu, anda boleh menambah pembolehubah secara semula jadi) atau 🎜 memanjangkan kitaran hayatnya 🎜 (apabila skop dirujuk, ia secara semula jadi akan dilanjutkan) 🎜 rrreee 🎜Gelung pertama mengisytiharkan beberapa fungsi dan berkongsi pembolehubah i global (kedua-dua pembolehubah dan pengisytiharan fungsi digalakkan). 🎜Gelung kedua mentakrifkan beberapa fungsi pelaksanaan segera dan melepasi nilai i, jadi setiap nilai i mempunyai skopnya sendiri. 🎜Ini adalah contoh yang lebih baik, penutupan + gelung, tetapi yang ini istimewa, penutupan mengakses skopnya sendiri. 🎜 🎜🎜Sudah tentu, modul yang paling baik merangkumi idea penutupan ialah modul, yang mengembalikan kaedah, yang memperkenalkan skop dengan berkesan. 🎜🎜 🎜🎜Penutupan: Ia adalah cara untuk mendapatkan dan mengakses skop tertentu, yang boleh diakses secara luaran atau dalam dirinya. 🎜🎜

    balas
    0
  • PHP中文网

    PHP中文网2017-05-16 13:37:00

    Dua fungsi terbesar

    1. Baca pembolehubah dalaman fungsi

    2. Sentiasa simpan nilai berubah dalam ingatan

    Saya tidak akan menerangkan secara terperinci tentang yang pertama, tetapi lihat yang kedua sebagai contoh

    function f1(){
        var n=999;
        nAdd=function(){n+=1}
        function f2(){
          alert(n);
        }
        return f2;
      }
      var result=f1();
      result(); // 999
      nAdd();
      result(); // 1000   

    hasil sebenarnya adalah fungsi penutupan f2. Ia dijalankan dua kali, kali pertama nilainya ialah 999, kali kedua nilainya ialah 1000. Ini membuktikan bahawa pembolehubah tempatan n dalam fungsi f1 sentiasa disimpan dalam ingatan dan tidak dikosongkan secara automatik selepas f1 dipanggil.
    Kenapa ini berlaku? Sebabnya ialah f1 ialah fungsi induk bagi f2, dan f2 diberikan kepada pembolehubah global, yang menyebabkan f2 sentiasa berada dalam ingatan, dan kewujudan f2 bergantung kepada f1, jadi f1 sentiasa dalam ingatan dan tidak akan dipadamkan. selepas panggilan selesai , dikitar semula oleh mekanisme pengumpulan sampah (kutipan sampah).
    Perkara lain yang perlu diberi perhatian dalam kod ini ialah baris "nAdd=function(){n+=1}". Pertama sekali, kata kunci var tidak digunakan sebelum nAdd, jadi nAdd ialah pembolehubah global, bukan pembolehubah setempat. Kedua, nilai nAdd ialah fungsi tanpa nama, dan fungsi tanpa nama ini sendiri juga merupakan penutup, jadi nAdd adalah bersamaan dengan penetap, yang boleh beroperasi pada pembolehubah tempatan di dalam fungsi dari luar fungsi

    • Urus pembolehubah persendirian dan kaedah persendirian, dan rangkumkan perubahan kepada pembolehubah (keadaan) dalam persekitaran yang selamat

    • Enkapsulasi kod ke dalam borang penutupan dan tunggu untuk digunakan pada masa yang sesuai, seperti melaksanakan kari dan de-kari

    • Perkara yang perlu diambil perhatian:

      • Oleh kerana beberapa sumber dalam penutupan tidak boleh dikeluarkan secara automatik, mudah untuk menyebabkan kebocoran memori Penyelesaiannya ialah memadam semua pembolehubah tempatan yang tidak digunakan sebelum keluar dari fungsi.

      • Penutupan akan mengubah nilai pembolehubah di dalam fungsi induk di luar fungsi induk. Oleh itu, jika anda menggunakan fungsi induk sebagai objek, penutupan sebagai kaedah awamnya dan pembolehubah dalaman sebagai nilai peribadinya, anda mesti berhati-hati untuk tidak mengubah nilai pembolehubah di dalam fungsi induk.

    balas
    0
  • 世界只因有你

    世界只因有你2017-05-16 13:37:00

    Jika saya katakan, set_passLine sebenarnya adalah fungsi dua parameter, bolehkah anda menerimanya?

    def set_passLine(passline)(val): # 虽然这不符合语法
        pass

    Fungsi jumlah ini

    def set_passLine(passline,val):
        pass

    adalah setara dari segi fungsi, tetapi yang pertama tidak perlu dipanggil dengan semua parameter sekaligus.

    Selain itu, cara penulisan pertama boleh mencapai fungsi yang sama seperti kelas:

    def set_passLine(passline):
        def cmp(val):
            pass
        def resetPassLine(newPassline):
            passline=newPassline
            pass
        return (cmp,resetPassLine)

    Walaupun ini adalah pelaksanaan berbeza bagi fungsi yang sama. Tetapi orang semakin mendapati bahawa pengaturcaraan berfungsi lebih baik daripada kaedah lain yang lebih baik dan lebih jelas dari segi saiz kod (tetapi keperluan untuk pengaturcara semakin tinggi dan lebih tinggi).

    Beri saya pautan, tetapi saya menulisnya dalam js: http://zonxin.github.io/post/...

    P.S.
    Pengaturcaraan berorientasikan objek ialah menganggap semua "objek" sebagai objek Pengaturcaraan ialah menggunakan objek untuk mensimulasikan tingkah laku "objek", iaitu untuk mensimulasikan operasi "dunia" tertentu.
    Pengaturcaraan fungsional hanya mengambil berat tentang keadaan awal "objek" dan keadaan akhir "objek" selepas melalui fungsi, tanpa mengambil berat tentang proses Pengaturcaraan adalah untuk menangani komposisi fungsi ini.

    balas
    0
  • 滿天的星座

    滿天的星座2017-05-16 13:37:00

    Saya sentiasa memahaminya dengan cara ini: melindungi pembolehubah dalaman dan beroperasi melalui API terdedah.

    var name="meimei"
    function Private(){
        var name = "leilei";
        return {
            getName:function(){
                console.log(name)
            },
            setName:function(val){
                name = val;
            }
        }
    }
    var private = Private();
    private.getName()//"leilei"
    private.setName("xiaoming")
    private.getName()//"xiaoming"
    name//"meimei"
    //通过暴漏API来操作内部变量。
    jquery:
    (function(){
    ...
        window.$=window.jquery=window.jQuery=...
    })
    //一个匿名自执行函数通过window暴漏jquery,内部变量不会受到其他全局变量的污染,只能通过$的API进行操作。

    Di atas adalah pemahaman peribadi saya

    balas
    0
  • PHP中文网

    PHP中文网2017-05-16 13:37:00

    Elakkan pencemaran berubah-ubah, tetapi jika dalam ES6, gunakan let dan const untuk menyelesaikan masalah ini

    balas
    0
  • 大家讲道理

    大家讲道理2017-05-16 13:37:00

    Di peringkat rendah
    Saya hanya tahu bahawa 1. Anda boleh mengakses pembolehubah setempat
    2 Ia sentiasa boleh disimpan dalam ingatan

    Jadi kekerapan penggunaan tidak boleh terlalu tinggi, kerana ia boleh menyebabkan kebocoran memori

    balas
    0
  • PHPz

    PHPz2017-05-16 13:37:00

    Jawab sesuatu yang mengagumkan saya 偏函数

    function logger(logType){
        return console.log.bind(console, logType); 
    }
    
    var info = logger('[INFO]'); 
    var error = logger('[ERROR]'); 
    
    info('this is an info'); 
    // => 
    // [INFO] this is an info
    
    error('this is an error'); 
    // => 
    // [ERROR] this is an error

    balas
    0
  • Batalbalas