国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

LeoHsiun / 1761人閱讀

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

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

一、變量的作用域

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

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

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

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

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

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

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

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

在上面的代碼中,函數(shù)fn2可以直接讀取其父函數(shù)fn1內(nèi)部的所有局部變量。但是反過來就不行,fn2內(nèi)部的局部變量,對fn1就是不可見的。
這就是 Javascript 語言特有的鏈?zhǔn)阶饔糜?/strong>,子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立
既然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 語言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數(shù)內(nèi)部的函數(shù)"。
所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。

四、閉包的用途

閉包最大用處有兩個,一個是前面提到的可以讀取函數(shù)內(nèi)部的變量,另一個就是讓這些變量的值始終保持在內(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。
這說明,函數(shù)fn1中的局部變量n一直保存在內(nèi)存中,并沒有在fn1調(diào)用后被自動清除。
為什么會這樣呢?原因就在于fn1fn2的父函數(shù),而fn2被賦給了一個全局變量,這導(dǎo)致fn2始終在內(nèi)存中,而fn2的存在依賴于fn1,因此fn1也始終在內(nèi)存中,不會在調(diào)用結(jié)束后,被垃圾回收機(jī)制回收。
這段代碼中另一個值得注意的地方,就是add = function(){ n+=1 }這一行。
首先函數(shù)add沒有使用var關(guān)鍵字來聲明,因此add是一個全局變量,而不是局部變量。
其次,add的值是一個匿名函數(shù),而這個匿名函數(shù)本身也是一個閉包,所以add相當(dāng)于是一個setter,可以在函數(shù)外部對函數(shù)內(nèi)部的局部變量進(jìn)行操作。

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

由于閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,因此內(nèi)存消耗很大,所以不能濫用閉包,否則會造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。

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

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

(完)

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/81718.html

相關(guān)文章

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

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

    tianren124 評論0 收藏0
  • 通過示例學(xué)習(xí)JavaScript閉包

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

    xingpingz 評論0 收藏0
  • 詳解js閉包

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

    Chiclaim 評論0 收藏0
  • JavaScript 閉包

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

    zhou_you 評論0 收藏0
  • 理解Javascript閉包

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

    dayday_up 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<