javascript - Apakah kegunaan penutupan dalam pembangunan praktikal?
PHPz
PHPz 2017-05-16 13:35:00
0
9
926

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?

PHPz
PHPz

学习是最好的投资!

membalas semua(9)
过去多啦不再A梦

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;
    }
})();
伊谢尔伦

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

巴扎黑

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 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. 🎜🎜
Ty80

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.

世界只因有你

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.

滿天的星座

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

Ty80

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

大家讲道理

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

PHPzhong

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
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan