Rumah > Soal Jawab > teks badan
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?
过去多啦不再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;
}
})();
伊谢尔伦2017-05-16 13:37:00
Simpan pembolehubah Selalunya saya menggunakannya untuk menggantikan pembolehubah global untuk mengelakkan pencemaran berubah
巴扎黑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
值,故每个i
peraturan skop leksikal
JS
, aksesnya adalah untuk mencari skop ke atas sehingga
. 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.
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 pembolehubahi
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. 🎜🎜PHP中文网2017-05-16 13:37:00
Dua fungsi terbesar
Baca pembolehubah dalaman fungsi
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.
世界只因有你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.
滿天的星座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
PHP中文网2017-05-16 13:37:00
Elakkan pencemaran berubah-ubah, tetapi jika dalam ES6, gunakan let dan const untuk menyelesaikan masalah ini
大家讲道理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
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