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

資訊專欄INFORMATION COLUMN

【JavaScript】【函數(shù)】閉包閉包!

he_xd / 675人閱讀

摘要:要想保存在循環(huán)過程中每一個的值,需要在匿名函數(shù)外部再套用一個匿名函數(shù),在這個匿名函數(shù)中定義另一個變量并且立即執(zhí)行來保存的值。這時最內(nèi)部的匿名函數(shù)訪問的是的值,所以數(shù)組中個匿名函數(shù)的返回值就是。才是匿名函數(shù)功能執(zhí)行的環(huán)境。

閉包,有人說它是一種設(shè)計(jì)理念,有人說所有的函數(shù)都是閉包。我不知道如何去定義它,我也不準(zhǔn)備去定義它,定義它就是限制了對它的理解。

我們依賴光來看清世間萬物,光卻遮住了黑暗。如同你腳下的路,讓你看不清前行的方向。

在這里寫一點(diǎn)我對閉包的理解。理解閉包的關(guān)鍵在于:外部函數(shù)調(diào)用之后其變量對象本應(yīng)該被銷毀,但閉包的存在使我們?nèi)匀豢梢栽L問外部函數(shù)的變量對象。

function outer() {
    var a = 1;
    return function() {
        return a;
    };
}
var b = outer();
console.log(b()); //1
模塊級作用域
(function(){
    var now = new Date();
    if (now.getMonth() == 0 && now.getDate() == 1) {
        alert("Happy new Year!");
    }
})();

這種方式常用來限制向全局作用域添加過多的變量和函數(shù)。

創(chuàng)建私有變量
(funcion() {
    var a = 1;
    setA = function(val){
        a = val;
    };
    getA = function(){
        return a;
    };
})();
console.log(a); //報錯
console.log(getA()); //1
setA(2);
console.log(getA()); //2

也可以這樣寫:

function outer(){
    var a = 1;
    return {
        setA: function(val) {
            a = val;  
        },
        getA: function() {
            return a;
        }
    };
}
var closure = outer();
console.log(a); //報錯
console.log(closure.getA()); //1
closure.setA(2);
console.log(closure.getA()); //2

第一個例子中,setAgetA都是全局變量,用于讀寫私有變量a。第二個例子中將這兩個方法作為一個對象返回并賦給一個全局變量closure,這樣當(dāng)outer執(zhí)行完畢后,這兩個方法(匿名函數(shù))連同外部函數(shù)中的變量對象(a)依然不會被銷毀。

閉包用于創(chuàng)建具有私有變量的實(shí)例對象,參考通過閉包創(chuàng)建具有私有屬性的實(shí)例對象

閉包只能取得包含函數(shù)中任何變量的最后一個值
function arrFunc() {
    var arr = [];
    for (var i=0; i<10; i++) {
        arr[i] = function() {
            return i;
        };
    }
    return arr;
}

arr數(shù)組中包含了10個匿名函數(shù),每個匿名函數(shù)都能訪問外部函數(shù)的變量i,那么i是多少呢?當(dāng)arrFunc執(zhí)行完畢后,其作用域被銷毀,但它的變量對象仍保存在內(nèi)存中,得以被匿名訪問,這時i的值為10。要想保存在循環(huán)過程中每一個i的值,需要在匿名函數(shù)外部再套用一個匿名函數(shù),在這個匿名函數(shù)中定義另一個變量并且立即執(zhí)行來保存i的值。

function arrFunc() {
    var arr = [];
    for (var i=0; i<10; i++) {
        arr[i] = function(num) {
            return function() {
                return num;
            };
        }(i);
    }
    return arr;
}
console.log(arrFunc()[1]()); //1

這時最內(nèi)部的匿名函數(shù)訪問的是num的值,所以數(shù)組中10個匿名函數(shù)的返回值就是1-10。

閉包中的this
var name = "window";
var obj = {
    name: "object",
    getName: function() {
        return function() {
            return this.name;
        };
    }
};
console.log(obj.getName()()); //window

obj.getName()()實(shí)際上是在全局作用域中調(diào)用了匿名函數(shù),this指向了window。這里要理解函數(shù)名與函數(shù)功能是分割開的,不要認(rèn)為函數(shù)在哪里,其內(nèi)部的this就指向哪里。window才是匿名函數(shù)功能執(zhí)行的環(huán)境。要想使this指向外部函數(shù)的執(zhí)行環(huán)境,可以這樣改寫:

var name = "window";
var obj = {
    name: "object",
    getName: function() {
        var that = this;
        return function() {
            return that.name;
        };
    }
};
console.log(obj.getName()()); //object

argumentsthis也有相同的問題。下面的情況也要注意:

var name = "window";
var obj = {
    name: "object",
    getName: function() {
        return this.name;
    }
};
obj.getName(); //object
(obj.getName = obj.getName)(); //window 非嚴(yán)格模式下

obj.getName();這時getName()是在對象obj的環(huán)境中執(zhí)行的,所以this指向obj
(obj.getName = obj.getName)賦值語句返回的是等號右邊的值,在全局作用域中返回,所以(obj.getName = obj.getName)();this指向全局。要把函數(shù)名和函數(shù)功能分割開來。

內(nèi)存泄漏

閉包會引用包含函數(shù)的整個變量對象,如果閉包的作用域鏈中保存著一個HTML元素,那么就意味著該元素?zé)o法被銷毀。所以我們有必要在對這個元素操作完之后主動銷毀。

function assignHandler() {
    var element = document.getElementById("someElement");
    var id = element.id;
    element.onclick = function() {
        alert(id);
    };
    element = null;
}
函數(shù)內(nèi)部的定時器

當(dāng)函數(shù)內(nèi)部的定時器引用了外部函數(shù)的變量對象時,該變量對象不會被銷毀。

(function() {
    var a = 0;
    setInterval(function(){
        console.log(a++);
    }, 1000);
})();
運(yùn)用閉包的關(guān)鍵

閉包引用外部函數(shù)變量對象中的值;

在外部函數(shù)的外部調(diào)用閉包。

轉(zhuǎn)載請注明出處:https://segmentfault.com/a/1190000004585904

文章不定期更新完善,如果能對你有一點(diǎn)點(diǎn)啟發(fā),我將不勝榮幸。

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

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

相關(guān)文章

  • Javascript閉包入門(譯文)

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

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

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

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

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

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

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

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

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

    sunsmell 評論0 收藏0
  • JavaScript 閉包

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

    zhou_you 評論0 收藏0

發(fā)表評論

0條評論

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