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

資訊專欄INFORMATION COLUMN

學(xué)習(xí)Javascript閉包(Closure)

LeoHsiun / 1828人閱讀

摘要:另一方面,函數(shù)外部無(wú)法直接讀取函數(shù)內(nèi)的局部變量。這說(shuō)明,函數(shù)中的局部變量一直保存在內(nèi)存中,并沒(méi)有在調(diào)用后被自動(dòng)清除。首先函數(shù)沒(méi)有使用關(guān)鍵字來(lái)聲明,因此是一個(gè)全局變量,而不是局部變量。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。

原文鏈接 - http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

一、變量的作用域

要理解閉包,首先必須理解 Javascript 特殊的變量作用域。
變量的作用域無(wú)非就是兩種:全局變量局部變量。
Javascript 語(yǔ)言的特殊之處,就在于函數(shù)內(nèi)部可以直接讀取全局變量。

var n = 999;
function foo () {
    console.log(n);
}
foo(); // 999

另一方面,函數(shù)外部無(wú)法直接讀取函數(shù)內(nèi)的局部變量。

function foo () {
    var n = 999;
}
console.log(n); // error

這里有一個(gè)地方需要注意,在函數(shù)內(nèi)部一定要使用var聲明變量,否則這個(gè)變量就會(huì)聲明是一個(gè)全局變量!

function foo () {
    n = 999;
}
foo();
console.log(n); // 999
二、如何從外部讀取局部變量?

出于種種原因,我們有時(shí)候需要得到函數(shù)內(nèi)的局部變量。但是,前面已經(jīng)說(shuō)過(guò)了,正常情況下,這是辦不到的,只有通過(guò)變通方法才能實(shí)現(xiàn)。
那就是在函數(shù)的內(nèi)部,再定義一個(gè)函數(shù)。

function fn1 () {
    var n = 999;
    function fn2 () {
        console.log(n); // 999
    }
}

在上面的代碼中,函數(shù)fn2可以直接讀取其父函數(shù)fn1內(nèi)部的所有局部變量。但是反過(guò)來(lái)就不行,fn2內(nèi)部的局部變量,對(duì)fn1就是不可見(jiàn)的。
這就是 Javascript 語(yǔ)言特有的鏈?zhǔn)阶饔糜?/strong>,子對(duì)象會(huì)一級(jí)一級(jí)地向上尋找所有父對(duì)象的變量。所以,父對(duì)象的所有變量,對(duì)子對(duì)象都是可見(jiàn)的,反之則不成立。
既然fn2可以讀取fn1中的局部變量,那么只要把fn2作為返回值,就可以在fn1外部讀取它的內(nèi)部變量了。

function fn1 () {
    var n = 999;
    function fn2 () {
        console.log(n); 
    }
    return fn2;
}
var result = fn1();
result(); // 999

這里的fn2函數(shù),就是閉包。

三、閉包的概念

各種專業(yè)文獻(xiàn)上的"閉包"(closure)定義非常抽象,很難看懂。
我的理解是,閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。
由于在 Javascript 語(yǔ)言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡(jiǎn)單理解成"定義在一個(gè)函數(shù)內(nèi)部的函數(shù)"。
所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的一座橋梁。

四、閉包的用途

閉包最大用處有兩個(gè),一個(gè)是前面提到的可以讀取函數(shù)內(nèi)部的變量,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中。

function fn1 () {
    var n = 999;
    add = function(){
        n += 1
    }
    function fn2 () {
        alert(n);
    }
    return fn2;
}
var result = fn1();
result(); // 999
add();
result(); // 1000

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

五、使用閉包的注意點(diǎn)

由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,因此內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁(yè)的性能問(wèn)題,在IE中可能導(dǎo)致內(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)部變量的值。

六、思考題

如果能理解下面兩段代碼的運(yùn)行結(jié)果,應(yīng)該就算理解閉包的運(yùn)行機(jī)制了。
代碼片段一。

var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        return function(){
            return this.name;
        };
    }
};
console.log(object.getNameFunc()());
代碼片段二。
var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        var that = this;
        return function(){
            return that.name;
        };
    }
};
console.log(object.getNameFunc()());

提示:這兩個(gè)問(wèn)題的關(guān)鍵在于this指向誰(shuí)。

(完)

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

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

相關(guān)文章

  • JavaScript閉包closure)的學(xué)習(xí)

    摘要:下面讓我們來(lái)看一個(gè)例子上面就是一個(gè)最簡(jiǎn)單的閉包。閉包的作用接下來(lái)來(lái)談?wù)勯]包的作用,初學(xué)者剛接觸時(shí)肯定是一臉懵逼,閉包的用處究竟是什么,下面就來(lái)談一談。同時(shí)也得感謝參考文章閉包的應(yīng)用讓你分分鐘理解閉包閉包,懂不懂由你,反正我是懂了 昨天在看思否時(shí),發(fā)現(xiàn)了一篇文章是關(guān)于JavaScript如何實(shí)現(xiàn)重載的,由于以前也和學(xué)長(zhǎng)討論過(guò)JavaScript是否能夠重載,就點(diǎn)進(jìn)去看了看,發(fā)現(xiàn)里面的兩個(gè)...

    tianren124 評(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
  • 詳解js閉包

    摘要:但閉包的情況不同嵌套函數(shù)的閉包執(zhí)行后,,然后還在被回收閉包會(huì)使變量始終保存在內(nèi)存中,如果不當(dāng)使用會(huì)增大內(nèi)存消耗。每個(gè)函數(shù),不論多深,都可以認(rèn)為是全局的子作用域,可以理解為閉包。 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn),也是它的特色,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)。 閉包的特性 閉包有三個(gè)特性: 1.函數(shù)嵌套函數(shù) 2.函數(shù)內(nèi)部可以引用外部的參數(shù)和變量 3.參數(shù)和變量不會(huì)...

    Chiclaim 評(píng)論0 收藏0
  • JavaScript 閉包

    摘要:閉包的注意事項(xiàng)通常,函數(shù)的作用域及其所有變量都會(huì)在函數(shù)執(zhí)行結(jié)束后被銷毀。但是,在創(chuàng)建了一個(gè)閉包以后,這個(gè)函數(shù)的作用域就會(huì)一直保存到閉包不存在為止。最后通過(guò)釋放了和對(duì)閉包的引用。從而使用閉包模塊化代碼,減少全局變量的污染。 JavaScript 閉包 原文鏈接 什么是閉包(Closure) 簡(jiǎn)單講,閉包就是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)。 MDN 上面這么說(shuō):閉包是一種特殊的...

    zhou_you 評(píng)論0 收藏0
  • 理解Javascript閉包

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

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

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

0條評(píng)論

閱讀需要支付1元查看
<