成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

JavaScript——閉包理解

AprilJ / 2340人閱讀

摘要:閉包占用大量?jī)?nèi)存通常,函數(shù)的作用域及其所有的變量都會(huì)在函數(shù)執(zhí)行結(jié)束后被銷(xiāo)毀。也就是說(shuō),可以通過(guò)閉包創(chuàng)建私有作用域?qū)⒛承┳兞孔鳛榫植孔兞?,避免使用全局變量而占用過(guò)多的內(nèi)存。

JavaScript——閉包理解 1、閉包是什么,如何使用?

閉包指的是函數(shù)對(duì)象可以通過(guò)作用域鏈相互關(guān)聯(lián)起來(lái),函數(shù)體內(nèi)部的變量都可以保存在函數(shù)作用域內(nèi),也就是說(shuō)閉包有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)。
下面是一個(gè)簡(jiǎn)單閉包的函數(shù)

function mackFn() {
    var name = "Husky"
    function sayName () {
        console.log("name:" + name)
    }
    return sayName
}
var myFn = mackFn()
myFn()

mackFn()創(chuàng)建了一個(gè)局部變量name和一個(gè)名為sayName()的函數(shù)。sayName()是定義在mackFn()里的內(nèi)部函數(shù),sayName()可以訪問(wèn)到外部函數(shù)的變量,所以sayName()可以使用父函數(shù)mackFn()函數(shù)中聲明的變量name。myFn是執(zhí)行了mackFn時(shí)創(chuàng)建的sayName函數(shù)實(shí)例的引用,且mackFn()函數(shù)形成閉包,所以sayName實(shí)例仍可訪問(wèn)其詞法作用域的變量,即可以訪問(wèn)name。

2、閉包的作用有哪些?
閉包其實(shí)用處很大,通過(guò)上面的例子,可以了解到閉包允許將數(shù)據(jù)與其所操作的某些數(shù)據(jù)關(guān)聯(lián)起來(lái),因此但我們使用只有一個(gè)方法的對(duì)象的地方,就可以使用閉包。閉包可以用來(lái)訪問(wèn)私有變量和模擬私有方法

通過(guò)閉包可以訪問(wèn)私有變量的共有方法

閉包技術(shù)可以用來(lái)共享私有變量,下面的例子創(chuàng)建了一個(gè)addPrivateProperty()函數(shù)來(lái)實(shí)現(xiàn)私有屬性存取器方法。這個(gè)函數(shù)給對(duì)象o增加了屬性存取器方法,方法名稱(chēng)為"get" + name"set" + name。如果提供了一個(gè)判定函數(shù), setter方法就會(huì)用它來(lái)檢測(cè)參數(shù)的合法性,然后再存儲(chǔ)它, 如果判定函數(shù)返回false,setter方法拋出異常。對(duì)于兩個(gè)存取器方法來(lái)說(shuō)value這個(gè)變量是私有的,沒(méi)有辦法繞過(guò)存取器方法來(lái)設(shè)置或修改這個(gè)值。

function addPrivateProperty(o, name, predicate){
    var value   // 私有變量
    
    // 私有函數(shù)
    o["get" + name] = function() {
        return value
    }
    o["set" + name] = function(v) {
        if (predicate && !predicate(v)){
            throw Error("set" + name + ": invalid value" + v)
        } else {
            value = v
        }
    }
}

var o = {}   //設(shè)置一個(gè)空對(duì)象
addPrivateProperty(o, "Name",function(x){
    return typeof x == "string"
})
o.setName("Frank")  //設(shè)置屬性值
console.log(o.getName())   // => "Frank"

上述的例子中,在同一個(gè)作用域鏈中定義了兩個(gè)閉包,這兩個(gè)閉包共同享用同樣的私有變量或變量。

3、閉包存在的問(wèn)題

閉包中的循環(huán)陷阱

通過(guò)循環(huán)創(chuàng)建多個(gè)閉包會(huì)產(chǎn)生一定的缺陷,即閉包只能取得包含函數(shù)中任何變量的最后一個(gè)值, 下面的第一個(gè)例子中,定時(shí)器函數(shù)返回的是10, 因?yàn)槊總€(gè)函數(shù)的作用域都保存著createFn()函數(shù)的活動(dòng)對(duì)象。所以它們引用的都是同一個(gè)變量n。當(dāng)createFn()函數(shù)中,執(zhí)行完循環(huán)之后變量n的值是10,此時(shí)每個(gè)定時(shí)器函數(shù)都應(yīng)用這保存變量n的同一個(gè)變量對(duì)象,所以在每個(gè)函數(shù)內(nèi)部n的值都是10

function createFn() {
  for (var n = 0; n < 5; n++) {
    setTimeout(function() {
      return console.log(n);
    }, 100 * n);
  }
}
createFn()   // => 5 5 5 5 5

可以通過(guò)定義了一個(gè)匿名函數(shù)并將立即執(zhí)行該匿名函數(shù),在調(diào)用每個(gè)匿名函數(shù)的時(shí)候,傳入了變量num,由于函數(shù)參數(shù)是按值傳遞的,所以就會(huì)將變量k的當(dāng)前值賦值給匿名函數(shù)的參數(shù)num,而在這個(gè)匿名函數(shù)的內(nèi)部,又會(huì)創(chuàng)建并返回了一個(gè)訪問(wèn)k的閉包,因此定時(shí)器函數(shù)中都有自己k變量的一個(gè)副本,便可以返回不同的數(shù)值。

function createFn() {
  for (var k = 0; k < 10; k++) {
    (function(num) {
      setTimeout(function() {
        return console.log(num);
      }, 100 * k);
    })(k);
  }
}
createFn();  // => 1 2 3 4 5

閉包占用大量?jī)?nèi)存

通常,函數(shù)的作用域及其所有的變量都會(huì)在函數(shù)執(zhí)行結(jié)束后被銷(xiāo)毀。但是,當(dāng)函數(shù)一旦返回了閉包,這個(gè)函數(shù)的作用域?qū)?huì)一直在內(nèi)存中保存到閉包不存在為止。
但是可以通過(guò)模仿塊級(jí)作用域來(lái)實(shí)現(xiàn)。通過(guò)創(chuàng)建并立即調(diào)用一個(gè)函數(shù),函數(shù)內(nèi)部的所有變量都會(huì)被立即銷(xiāo)毀(除某些變量賦值給了包含作用域中的變量),這樣既可以執(zhí)行其中的代碼,又不會(huì)在內(nèi)存中留在對(duì)該函數(shù)的引用。

function Fn(count) {
    (function() {
        for(var i = 0; i < count; i++) {
            console.log(i)
        }
    })()
    console.log("i:" + i)  // 拋出錯(cuò)誤
}
Fn(5)

通過(guò)創(chuàng)建函數(shù)Fn(),在for循環(huán)外部插入一個(gè)塊級(jí)作用域(私有作用域),在匿名函數(shù)中定義的任何變量,都會(huì)在執(zhí)行結(jié)束的時(shí)候被銷(xiāo)毀。因此,變量i只能坐在循環(huán)中使用,使用后就被銷(xiāo)毀。而在使用作用域中能夠訪問(wèn)count變量,是因?yàn)檫@個(gè)匿名函數(shù)是一個(gè)閉包,它能夠訪問(wèn)包含作用域中的所有變量。

4、性能優(yōu)化之內(nèi)存管理

通過(guò)創(chuàng)建私有作用域,在全局作用域中被函數(shù)外部使用,從而限制向全局作用域中添加過(guò)多的變量和函數(shù)。通過(guò)此方法不僅可以使用自己變量,而且不用擔(dān)心搞亂全局作用域。也就是說(shuō),可以通過(guò)閉包創(chuàng)建私有作用域?qū)⒛承┳兞孔鳛榫植孔兞?,避免使用全局變量而占用過(guò)多的內(nèi)存。

總結(jié)

閉包有著其優(yōu)點(diǎn),可以利用其優(yōu)點(diǎn)實(shí)現(xiàn)很多功能,如閉包可以用來(lái)訪問(wèn)私有變量和模擬私有方法(訪問(wèn)私有屬性的模式有很多,以后總結(jié))等等,但是因?yàn)閯?chuàng)建閉包必須維護(hù)額外的作用域,所以過(guò)渡使用閉包會(huì)占用大量的內(nèi)存。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/107571.html

相關(guān)文章

  • 理解 JavaScript 閉包

    摘要:如何在初學(xué)就理解閉包你需要接著讀下去。這樣定義閉包是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合。小結(jié)閉包在中隨處可見(jiàn)。閉包是中的精華部分,理解它需要具備一定的作用域執(zhí)行棧的知識(shí)。 這是本系列的第 4 篇文章。 作為 JS 初學(xué)者,第一次接觸閉包的概念是因?yàn)閷?xiě)出了類(lèi)似下面的代碼: for (var i = 0; i < helpText.length; i++) { var item = he...

    寵來(lái)也 評(píng)論0 收藏0
  • 理解Javascript閉包

    摘要:但是閉包也不是什么復(fù)雜到不可理解的東西,簡(jiǎn)而言之,閉包就是閉包就是函數(shù)的局部變量集合,只是這些局部變量在函數(shù)返回后會(huì)繼續(xù)存在??上У氖牵](méi)有提供相關(guān)的成員和方法來(lái)訪問(wèn)閉包中的局部變量。 (收藏自 技術(shù)狂) 前言:還是一篇入門(mén)文章。Javascript中有幾個(gè)非常重要的語(yǔ)言特性——對(duì)象、原型繼承、閉包。其中閉包 對(duì)于那些使用傳統(tǒng)靜態(tài)語(yǔ)言C/C++的程序員來(lái)說(shuō)是一個(gè)新的語(yǔ)言特性。本文將...

    dayday_up 評(píng)論0 收藏0
  • Javascript閉包入門(mén)(譯文)

    摘要:也許最好的理解是閉包總是在進(jìn)入某個(gè)函數(shù)的時(shí)候被創(chuàng)建,而局部變量是被加入到這個(gè)閉包中。在函數(shù)內(nèi)部的函數(shù)的內(nèi)部聲明函數(shù)是可以的可以獲得不止一個(gè)層級(jí)的閉包。 前言 總括 :這篇文章使用有效的javascript代碼向程序員們解釋了閉包,大牛和功能型程序員請(qǐng)自行忽略。 譯者 :文章寫(xiě)在2006年,可直到翻譯的21小時(shí)之前作者還在完善這篇文章,在Stackoverflow的How do Java...

    Fourierr 評(píng)論0 收藏0
  • 【譯】理解JavaScript閉包

    摘要:當(dāng)面試中讓我解釋一下閉包時(shí)我懵逼了。這個(gè)解釋開(kāi)始可能有點(diǎn)晦澀,讓我們抽絲剝繭摘下閉包的真面目。此文不詳述作用域有專(zhuān)門(mén)的主題闡述,不過(guò)作用域是理解閉包原理的基礎(chǔ)。這才是閉包的真正便利之處。閉包使用不當(dāng)就會(huì)很坑。 原文鏈接 為什么深度學(xué)習(xí)JavaScript? JavaScript如今是最流行的編程語(yǔ)言之一。它運(yùn)行在瀏覽器、服務(wù)器、移動(dòng)設(shè)備、桌面應(yīng)用,也可能包括冰箱。無(wú)需我舉其他再多不相干...

    岳光 評(píng)論0 收藏0
  • 通過(guò)示例學(xué)習(xí)JavaScript閉包

    摘要:譯者按在上一篇博客,我們通過(guò)實(shí)現(xiàn)一個(gè)計(jì)數(shù)器,了解了如何使用閉包,這篇博客將提供一些代碼示例,幫助大家理解閉包。然而,如果通過(guò)代碼示例去理解閉包,則簡(jiǎn)單很多。不過(guò),將閉包簡(jiǎn)單地看做局部變量,理解起來(lái)會(huì)更加簡(jiǎn)單。 - 譯者按: 在上一篇博客,我們通過(guò)實(shí)現(xiàn)一個(gè)計(jì)數(shù)器,了解了如何使用閉包(Closure),這篇博客將提供一些代碼示例,幫助大家理解閉包。 原文: JavaScript Clos...

    xingpingz 評(píng)論0 收藏0
  • JavaScript中的閉包

    摘要:閉包引起的內(nèi)存泄漏總結(jié)從理論的角度將由于作用域鏈的特性中所有函數(shù)都是閉包但是從應(yīng)用的角度來(lái)說(shuō)只有當(dāng)函數(shù)以返回值返回或者當(dāng)函數(shù)以參數(shù)形式使用或者當(dāng)函數(shù)中自由變量在函數(shù)外被引用時(shí)才能成為明確意義上的閉包。 文章同步到github js的閉包概念幾乎是任何面試官都會(huì)問(wèn)的問(wèn)題,最近把閉包這塊的概念梳理了一下,記錄成以下文章。 什么是閉包 我先列出一些官方及經(jīng)典書(shū)籍等書(shū)中給出的概念,這些概念雖然...

    HmyBmny 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<