国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

javascript - 閉包在實(shí)際開(kāi)發(fā)上有什麼用?
PHPz
PHPz 2017-05-16 13:35:00
0
9
1122

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

誰(shuí)能舉個(gè)更好的例子來(lái)說(shuō)明閉包的作用???

PHPz
PHPz

學(xué)習(xí)是最好的投資!

全部回覆(9)
過(guò)去多啦不再A夢(mèng)

延長(zhǎng)局部變數(shù)的生命週期,封裝私有變數(shù)

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ò)查詢(xún)后臺(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 局部變量隨即被銷(xiāo)毀,而此時(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;
    }
})();
伊謝爾倫

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

巴扎黑

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

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

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

。

閉包用來(lái)增加變數(shù)(能訪問(wèn)某作用域,自然能加變數(shù))或延長(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)    
}
i變量(變量和函數(shù)聲明都提升了)。
第二個(gè)循環(huán)是定義了幾個(gè)立即執(zhí)行函數(shù),又傳遞了i值,故每個(gè)i第一個(gè)循環(huán)是聲明了幾個(gè)函數(shù),共享全域
值都有自己的作用域。 這個(gè)是一個(gè)比較好的例子,閉包+循環(huán),只是這個(gè)比較特別,閉包訪問(wèn)自身的作用域。

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

閉包:就是一個(gè)取得並存取某個(gè)作用域,可在外存取或自身內(nèi)部存取。

??
Ty80

最大的兩個(gè)作用

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

  2. 讓變數(shù)值始終保持在記憶體

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

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

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

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

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

  • 需要注意的:

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

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

世界只因有你

如果我說(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)呼叫。

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

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

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

給個(gè)連結(jié)吧,但是是我用 js 寫(xiě)的:http://zonxin.github.io/post/...

P.S.
物件導(dǎo)向的程式就是把,所有的「物體」看為對(duì)象,程式設(shè)計(jì)就是,使用物件模擬「物體」的行為,也就是模擬某個(gè)「世界」的運(yùn)作。
而函數(shù)式編程,只關(guān)心「物體」的初始狀態(tài)和「物體」經(jīng)過(guò)函數(shù)之後的最終狀態(tài),而不必關(guān)心其中的過(guò)程,編程就是處理這些函數(shù)的複合。

滿(mǎn)天的星座

我一直是這麼理解的:保護(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è)人理解

Ty80

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

大家講道理

初級(jí)程度來(lái)看
只知道1、可以存取到局部變數(shù)
2、可以一直儲(chǔ)存在記憶體中

所以使用頻率不宜過(guò)高,會(huì)造成記憶體洩漏

PHPzhong

回答我印象深刻的 偏函數(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 info

error('this is an error'); 
// => 
// [ERROR] this is an error
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板