成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Javascript 閉包

edagarli / 2094人閱讀

摘要:總結(jié)閉包的作用域鏈如下圖通過上述分析我們還可以看出,閉包有一個(gè)不同于普通函數(shù)的特性,就是它會(huì)攜帶包含它的函數(shù)的作用域,因此會(huì)占用更多內(nèi)存。

閉包的作用域鏈

閉包是有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù),比如:

function createFunc(words) {
    return function() {
        return words;
    }
}
var func = createFunc("Hello World!")
func();
// "Hello World!"

上述例子中createFunc的返回值是一個(gè)函數(shù)(閉包),這個(gè)返回值在調(diào)用時(shí)仍然可以訪問createFuncwords屬性,這是為什么呢?還記得在之前的文章Javascript 變量、作用域和內(nèi)存問題中提到的,一個(gè)函數(shù)在創(chuàng)建時(shí),會(huì)生成一個(gè)內(nèi)部屬性[[scope]],這個(gè)屬性包含函數(shù)被創(chuàng)建的作用域中對(duì)象的集合,也就包括了createFunc的活動(dòng)對(duì)象,而如果沒有閉包,createFunc的活動(dòng)對(duì)象在調(diào)用結(jié)束時(shí)就可以進(jìn)入GC序列,只有銷毀對(duì)閉包的引用,即func = null,才會(huì)使createFunc的活動(dòng)對(duì)象被GC。
總結(jié)閉包的作用域鏈如下圖:

通過上述分析我們還可以看出,閉包有一個(gè)不同于普通函數(shù)的特性,就是它會(huì)攜帶包含它的函數(shù)的作用域,因此會(huì)占用更多內(nèi)存。

閉包與變量

閉包的作用域鏈決定了閉包只能包含外部函數(shù)中任何變量的最終值,舉個(gè)例子:

function createFunctions(){
    var result = new Array();
    for (var i=0; i < 10; i++){
        result[i] = function(){
            return i;
        };
    }
    return result;
}
var result = createFunctions();
result[3](); // 10

上述例子中,我們?cè)?b>createFunctions函數(shù)中,通過for循環(huán),創(chuàng)建了多個(gè)函數(shù),并期望每一個(gè)都能返回創(chuàng)建它時(shí)的索引值,但結(jié)果發(fā)現(xiàn),每一個(gè)函數(shù)都只能返回i的最終值(由于ECMAScript中沒有塊級(jí)作用域,因此icreateFunctions中的局部變量),之所以是這樣的結(jié)果,是因?yàn)槊恳粋€(gè)閉包能夠訪問到的i都是對(duì)局部變量i的引用,由于這種情況的存在,因此我們發(fā)現(xiàn)很多閉包都是這樣寫的:

function createFunctions(){
    var result = new Array();
    for (var i=0; i < 10; i++){
        result[i] = function(num){
            return function() {
                return num;
            }    
        }(i);
    }
    return result;
}
var result = createFunctions();
result[3](); // 3

原理就是將動(dòng)態(tài)的局部變量參數(shù)化,這樣每一個(gè)閉包都保存了該局部變量某個(gè)時(shí)刻的副本。

在閉包中使用this

this是基于執(zhí)行環(huán)境綁定的,如果是全局函數(shù),那么thiswindow,如果是某個(gè)對(duì)象的函數(shù),那么this指這個(gè)對(duì)象,而匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此閉包中的this一般指window,比如:

var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        return function(){
            return this.name;
        };
    }
};
console.log(object.getNameFunc()()); //"The Window"

上述例子中,閉包是在全局環(huán)境中執(zhí)行的,而我們知道,每個(gè)函數(shù)在執(zhí)行時(shí)會(huì)基于執(zhí)行環(huán)境自動(dòng)獲得this,因此this指向了window。
上述例子中,如何使閉包可以訪問object呢,可以做如下修改:

var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        var that = this;
        return function(){
            return that.name;
        };
    }
};
object.getNameFunc()()
// "My Object"
內(nèi)存泄漏

在之前的文章Javascript 變量、作用域和內(nèi)存問題提到過IE在版本9之前,ECMAScript對(duì)象和DOM對(duì)象的GC機(jī)制不同,循環(huán)引用會(huì)導(dǎo)致DOM對(duì)象永遠(yuǎn)不能被回收,學(xué)習(xí)完這一章節(jié)后才發(fā)現(xiàn)自己經(jīng)常寫的一段代碼就存在這樣的問題!-_-,書中也提到了這個(gè)例子:

function assignHandler(){
    var element = document.getElementById("someElement");
    element.onclick = function(){
        console.log(element.id);
    };
}

上面的代碼就創(chuàng)建了一個(gè)閉包作為element的事件處理程序,這里的循環(huán)引用體現(xiàn)在element的屬性onclick的值中存在對(duì)element的引用,即使退出assignHandler,element這個(gè)DOM對(duì)象也不會(huì)被引用計(jì)數(shù)機(jī)制GC,那么不在閉包中顯式地引用element,總可以了吧,就比如:

function assignHandler(){
    var element = document.getElementById("someElement");
    var id = element.id;
    element.onclick = function(){
        console.log(id);
    };
}

答案是不行的,因?yàn)殚]包中無論如何都是要保存一份對(duì) assignHandler活動(dòng)對(duì)象的引用的,自然包含element。
之前提到過,由于閉包中保存的只是函數(shù)活動(dòng)對(duì)象的引用,那么閉包中能夠訪問的變量就具有動(dòng)態(tài)性,上個(gè)例子中,閉包由于引用了assignHandler的活動(dòng)對(duì)象,就引用了element,而element引用了一個(gè)DOM對(duì)象,那么,如果element不引用DOM對(duì)象,而是其他對(duì)象,比如null,那么element就可以被標(biāo)記清楚機(jī)制GC。

function assignHandler(){
    var element = document.getElementById("someElement");
    var id = element.id;
    element.onclick = function(){
        console.log(id);
    };
    element = null;
}

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94881.html

相關(guān)文章

  • Javascript閉包入門(譯文)

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

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

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

    dayday_up 評(píng)論0 收藏0
  • JavaScript閉包,只學(xué)這篇就夠了

    摘要:當(dāng)在中調(diào)用匿名函數(shù)時(shí),它們用的都是同一個(gè)閉包,而且在這個(gè)閉包中使用了和的當(dāng)前值的值為因?yàn)檠h(huán)已經(jīng)結(jié)束,的值為。最好將閉包當(dāng)作是一個(gè)函數(shù)的入口創(chuàng)建的,而局部變量是被添加進(jìn)這個(gè)閉包的。 閉包不是魔法 這篇文章使用一些簡單的代碼例子來解釋JavaScript閉包的概念,即使新手也可以輕松參透閉包的含義。 其實(shí)只要理解了核心概念,閉包并不是那么的難于理解。但是,網(wǎng)上充斥了太多學(xué)術(shù)性的文章,對(duì)于...

    CoderBear 評(píng)論0 收藏0
  • JavaScript深入之閉包

    摘要:深入系列第八篇,介紹理論上的閉包和實(shí)踐上的閉包,以及從作用域鏈的角度解析經(jīng)典的閉包題。定義對(duì)閉包的定義為閉包是指那些能夠訪問自由變量的函數(shù)。 JavaScript深入系列第八篇,介紹理論上的閉包和實(shí)踐上的閉包,以及從作用域鏈的角度解析經(jīng)典的閉包題。 定義 MDN 對(duì)閉包的定義為: 閉包是指那些能夠訪問自由變量的函數(shù)。 那什么是自由變量呢? 自由變量是指在函數(shù)中使用的,但既不是函數(shù)參數(shù)也...

    caige 評(píng)論0 收藏0
  • 還擔(dān)心面試官問閉包?

    摘要:一言以蔽之,閉包,你就得掌握。當(dāng)函數(shù)記住并訪問所在的詞法作用域,閉包就產(chǎn)生了。所以閉包才會(huì)得以實(shí)現(xiàn)。從技術(shù)上講,這就是閉包。執(zhí)行后,他的內(nèi)部作用域并不會(huì)消失,函數(shù)依然保持有作用域的閉包。 網(wǎng)上總結(jié)閉包的文章已經(jīng)爛大街了,不敢說筆者這篇文章多么多么xxx,只是個(gè)人理解總結(jié)。各位看官瞅瞅就好,大神還希望多多指正。此篇文章總結(jié)與《JavaScript忍者秘籍》 《你不知道的JavaScri...

    tinyq 評(píng)論0 收藏0
  • [學(xué)習(xí)筆記] JavaScript 閉包

    摘要:但是,必須強(qiáng)調(diào),閉包是一個(gè)運(yùn)行期概念。通過原型鏈可以實(shí)現(xiàn)繼承,而與閉包相關(guān)的就是作用域鏈。常理來說,一個(gè)函數(shù)執(zhí)行完畢,其執(zhí)行環(huán)境的作用域鏈會(huì)被銷毀。所以此時(shí),的作用域鏈雖然銷毀了,但是其活動(dòng)對(duì)象仍在內(nèi)存中。 學(xué)習(xí)Javascript閉包(Closure)javascript的閉包JavaScript 閉包深入理解(closure)理解 Javascript 的閉包JavaScript ...

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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<