色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

javascript - 閉包在實(shí)際開發(fā)中有什么用?

瀏覽:110日期:2023-09-19 15:26:01

問(wèn)題描述

javascript - 閉包在實(shí)際開發(fā)中有什么用?

看了一下視頻中對(duì)于閉包作用的解釋我還是表示不明白,比如說(shuō)截圖中這段代碼完全可以在cmp函數(shù)中加一個(gè)passline參數(shù)來(lái)實(shí)現(xiàn),沒(méi)必要使用閉包。

誰(shuí)能舉一個(gè)更加好的例子說(shuō)明閉包的作用啊?

問(wèn)題解答

回答1:

延長(zhǎng)局部變量的生命周期,封裝私有變量

2. 延續(xù)局部變量的壽命img 對(duì)象經(jīng)常用于進(jìn)行數(shù)據(jù)上報(bào),如下所示:var report = function( src ){ var img = new Image(); img.src = src;};report( ’http://xxx.com/getUserInfo’ );但是通過(guò)查詢后臺(tái)的記錄我們得知,因?yàn)橐恍┑桶姹緸g覽器的實(shí)現(xiàn)存在 bug,在這些瀏覽器下使用 report 函數(shù)進(jìn)行數(shù)據(jù)上報(bào)會(huì)丟失 30%左右的數(shù)據(jù),也就是說(shuō), report 函數(shù)并不是每一次都成功發(fā)起了 HTTP 請(qǐng)求。丟失數(shù)據(jù)的原因是 img 是 report 函數(shù)中的局部變量,當(dāng) report 函數(shù)的調(diào)用結(jié)束后, img 局部變量隨即被銷毀,而此時(shí)或許還沒(méi)來(lái)得及發(fā)出 HTTP 請(qǐng)求,所以此次請(qǐng)求就會(huì)丟失掉。現(xiàn)在我們把 img 變量用閉包封閉起來(lái),便能解決請(qǐng)求丟失的問(wèn)題:var report = (function(){ var imgs = []; return function( src ){var img = new Image();imgs.push( img );img.src = src; }})();回答2:

保存變量 大部分時(shí)候我是用它來(lái)替代全局變量 避免造成變量污染

回答3:

閉包解決的問(wèn)題:基于JS的詞法作用域規(guī)則,其訪問(wèn)是一直向上查找作用域,直到全局作用域。而想直接訪問(wèn)某個(gè)作用域可通過(guò)閉包解決。

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

bar詞法作用域可以訪問(wèn)foo內(nèi)部作用域,foo執(zhí)行后返回bar,最后賦值給baz,可以獲取并訪問(wèn)foo內(nèi)部作用域,只是標(biāo)識(shí)符不同而已。該代碼就使用了閉包,可以說(shuō)寫JS代碼處處可見閉包,使用閉包還有一個(gè)好處就是引用的作用域不會(huì)被垃圾回收處理,當(dāng)然不合理的使用會(huì)耗內(nèi)存

閉包用來(lái)增加變量(能訪問(wèn)某作用域,自然能加變量)或者延長(zhǎng)其生命周期(作用域被引用,自然會(huì)延長(zhǎng))

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) }

第一個(gè)循環(huán)是聲明了幾個(gè)函數(shù),共享全局i變量(變量和函數(shù)聲明都提升了)。第二個(gè)循環(huán)是定義了幾個(gè)立即執(zhí)行函數(shù),又傳遞了i值,故每個(gè)i值都有自己的作用域。這個(gè)是一個(gè)比較好的例子,閉包+循環(huán),只是這個(gè)比較特別,閉包訪問(wèn)自身的作用域。

當(dāng)然最能體現(xiàn)閉包思想的是模塊,返回一個(gè)方法,該方法就相當(dāng)引入了一個(gè)作用域。

閉包:就是一個(gè)獲取并訪問(wèn)某個(gè)作用域,可在外訪問(wèn)或者自身內(nèi)部訪問(wèn)。

回答4:

最大的兩個(gè)作用

讀取函數(shù)內(nèi)部變量

讓變量值始終保持在內(nèi)存里

第一個(gè)不贅述,看第二個(gè),舉例

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

result實(shí)際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n一直保存在內(nèi)存中,并沒(méi)有在f1調(diào)用后被自動(dòng)清除。為什么會(huì)這樣呢?原因就在于f1是f2的父函數(shù),而f2被賦給了一個(gè)全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中,不會(huì)在調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收。這段代碼中另一個(gè)值得注意的地方,就是'nAdd=function(){n+=1}'這一行,首先在nAdd前面沒(méi)有使用var關(guān)鍵字,因此nAdd是一個(gè)全局變量,而不是局部變量。其次,nAdd的值是一個(gè)匿名函數(shù)(anonymous function),而這個(gè)匿名函數(shù)本身也是一個(gè)閉包,所以nAdd相當(dāng)于是一個(gè)setter,可以在函數(shù)外部對(duì)函數(shù)內(nèi)部的局部變量進(jìn)行操作

管理私有變量和私有方法,將對(duì)變量(狀態(tài))的變化封裝在安全的環(huán)境中

將代碼封裝成一個(gè)閉包形式,等待時(shí)機(jī)成熟的時(shí)候再使用,比如實(shí)現(xiàn)柯里化和反柯里化

需要注意的:

由于閉包內(nèi)的部分資源無(wú)法自動(dòng)釋放,容易造成內(nèi)存泄露 解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。

閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對(duì)象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。

回答5:

如果我說(shuō), set_passLine 其實(shí)就是兩個(gè)參數(shù)的函數(shù),你能接受嗎?

def set_passLine(passline)(val): # 雖然這不符合語(yǔ)法 pass

這個(gè)和函數(shù)

def set_passLine(passline,val): pass

在功能上是等價(jià)的,但前者,不必一次性給出所有參數(shù)來(lái)調(diào)用。

另外,第一種寫法可以實(shí)現(xiàn)和類一樣的功能:

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

雖然這些都是相同功能的不同實(shí)現(xiàn)。但是人們?cè)絹?lái)越發(fā)現(xiàn)函數(shù)式編程比其他的方式更好,更好的意思是指在代碼量上更好,更清晰(但是對(duì)程序員的要求越來(lái)越高)。

給個(gè)鏈接吧,但是是我用 js 寫的:http://zonxin.github.io/post/...

P.S.面向?qū)ο蟮木幊叹褪前眩械摹拔矬w”看為對(duì)象,編程就是,使用對(duì)象模擬“物體”的行為,即模擬某個(gè)“世界”的運(yùn)行。而函數(shù)式編程,只關(guān)心“物體”的初始狀態(tài)和“物體”經(jīng)過(guò)函數(shù)之后的最終狀態(tài),而不必關(guān)心其中的過(guò)程,編程就是處理這些函數(shù)的復(fù)合。

回答6:

我一直是這么理解的:保護(hù)內(nèi)部變量,通過(guò)暴漏API進(jìn)行操作。

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'//通過(guò)暴漏API來(lái)操作內(nèi)部變量。jquery:(function(){... window.$=window.jquery=window.jQuery=...})//一個(gè)匿名自執(zhí)行函數(shù)通過(guò)window暴漏jquery,內(nèi)部變量不會(huì)受到其他全局變量的污染,只能通過(guò)$的API進(jìn)行操作。

以上是個(gè)人理解

回答7:

避免變量污染,但如果是在ES6中,用let和const就可以解決這個(gè)問(wèn)題了

回答8:

初級(jí)水平來(lái)看只知道1、可以訪問(wèn)到局部變量2、可以一直保存在內(nèi)存中

所以使用頻率不宜過(guò)高,會(huì)造成內(nèi)存泄漏

回答9:

答個(gè)我印象深刻的 偏函數(shù)

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 infoerror(’this is an error’); // => // [ERROR] this is an error

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 亚洲天堂一区二区 | 日本道久久 | 欧美成人高清免费大片观看 | 亚洲精品国产男人的天堂 | 国产在线a| 一区二区三区视频在线 | 成人精品一级毛片 | 手机看片神马午夜 | 亚洲午夜精品久久久久久抢 | 日韩在线视频免费 | 久久久综合网 | 一级国产精品一级国产精品片 | 91久久国产露脸精品免费 | 国产欧美日韩在线视频 | 性色网址| 国产一线视频在线观看高清 | 一级黄色欧美片 | 中文乱码字幕午夜无线观看 | 92精品国产自产在线观看 | 男人天堂网在线视频 | 成人牲交一极毛片 | 真实一级一级一片免费视频 | 99视频在线精品自拍 | 欧美一级人与动毛片免费播放 | 日本乱人伦在线观看免费 | 国产日韩精品欧美一区喷 | 日本老熟妇激情毛片 | 欧洲欧美成人免费大片 | 欧美成人a人片 | 国产精品国产三级在线高清观看 | 男人的天堂免费网站 | 九九精品久久久久久噜噜 | 高清欧美性xxxx成熟 | 亚洲精品国产字幕久久不卡 | 亚洲九九香蕉 | 亚洲精品一二区 | 99精品久久99久久久久 | 欧美一级毛片大片免费播放 | 免费日本视频 | 成人免费视频在线看 | 成人网视频在线观看免费 |