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

資訊專欄INFORMATION COLUMN

JavaScript 中 閉包 的詳解

longshengwang / 751人閱讀

摘要:局部變量,當定義該變量的函數調用結束時,該變量就會被垃圾回收機制回收而銷毀。如果在函數中不使用匿名函數創建閉包,而是通過引用一個外部函數,也不會出現循環引用的問題。

閉包是什么

在 JavaScript 中,閉包是一個讓人很難弄懂的概念。ECMAScript 中給閉包的定義是:閉包,指的是詞法表示包括不被計算的變量的函數,也就是說,函數可以使用函數之外定義的變量。

是不是看完這個定義感覺更加懵逼了?別急,我們來分析一下。

閉包是一個函數

閉包可以使用在它外面定義的變量

閉包存在定義該變量的作用域中

好像有點清晰了,但是使用在它外面定義的變量是什么意思,我們先來看看變量作用域。

變量作用域

變量可分為全局變量和局部變量。全局變量的作用域就是全局性的,在 js 的任何地方都可以使用全局變量。在函數中使用 var 關鍵字聲明變量,這時的變量即是局部變量,它的作用域只在聲明該變量的函數內,在函數外面是訪問不到該變量的。

var func = function(){
    var a = "linxin";
    console.log(a);         // linxin
}
func();
console.log(a);             // Uncaught ReferenceError: a is not defined

作用域相對比較簡單,我們不多講,來看看跟閉包關系比較大的變量生存周期。

變量生存周期

全局變量,生命周期是永久的。局部變量,當定義該變量的函數調用結束時,該變量就會被垃圾回收機制回收而銷毀。再次調用該函數時又會重新定義了一個新變量。

var func = function(){
    var a = "linxin";
    console.log(a);
}
func();

a 為局部變量,在 func 調用完之后,a 就會被銷毀了。

var func = function(){
    var a = "linxin";
    var func1 = function(){
        a += " a";
        console.log(a);
    }
    return func1;
}
var func2 = func();
func2();                    // linxin a
func2();                    // linxin a a
func2();                    // linxin a a a

可以看出,在第一次調用完 func2 之后,func 中的變量 a 變成 "linxin a",而沒有被銷毀。因為此時 func1 形成了一個閉包,導致了 a 的生命周期延續了。

這下子閉包就比較明朗了。

閉包是一個函數,比如上面的 func1 函數

閉包使用其他函數定義的變量,使其不被銷毀。比如上面 func1 調用了變量 a

閉包存在定義該變量的作用域中,變量 a 存在 func 的作用域中,那么 func1 也必然存在這個作用域中。

現在可以說,滿足這三個條件的就是閉包了。

下面我們通過一個簡單而又經典的例子來進一步熟悉閉包。

for (var i = 0; i < 4; i++) {
    setTimeout(function () {
        console.log(i)
    }, 0)
}

我們可能會簡單的以為控制臺會打印出 0 1 2 3,可事實卻打印出了 4 4 4 4,這又是為什么呢?我們發現,setTimeout 函數時異步的,等到函數執行時,for循環已經結束了,此時的 i 的值為 4,所以 function() { console.log(i) } 去找變量 i,只能拿到 4。

我們想起上一個例子中,閉包使 a 變量的值被保存起來了,那么這里我們也可以用閉包把 0 1 2 3 保存起來。

for (var i = 0; i < 4; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i)
        }, 0)
    })(i)
}

當 i=0 時,把 0 作為參數傳進匿名函數中,此時 function(i){} 此匿名函數中的 i 的值為 0,等到 setTimeout 執行時順著外層去找 i,這時就能拿到 0。如此循環,就能拿到想要的 0 1 2 3。

內存管理

在閉包中調用局部變量,會導致這個局部變量無法及時被銷毀,相當于全局變量一樣會一直占用著內存。如果需要回收這些變量占用的內存,可以手動將變量設置為null。

然而在使用閉包的過程中,比較容易形成 JavaScript 對象和 DOM 對象的循環引用,就有可能造成內存泄露。這是因為瀏覽器的垃圾回收機制中,如果兩個對象之間形成了循環引用,那么它們都無法被回收。

function func() {
    var test = document.getElementById("test");
    test.onclick = function () {
        console.log("hello world");
    }
}

在上面例子中,func 函數中用匿名函數創建了一個閉包。變量 test 是 JavaScript 對象,引用了 id 為 test 的 DOM 對象,DOM 對象的 onclick 屬性又引用了閉包,而閉包又可以調用 test ,因而形成了循環引用,導致兩個對象都無法被回收。要解決這個問題,只需要把循環引用中的變量設為 null 即可。

function func() {
    var test = document.getElementById("test");
    test.onclick = function () {
        console.log("hello world");
    }
    test = null;
}

如果在 func 函數中不使用匿名函數創建閉包,而是通過引用一個外部函數,也不會出現循環引用的問題。

function func() {
    var test = document.getElementById("test");
    test.onclick = funcTest;
}
function funcTest(){
    console.log("hello world");
}
更多文章:lin-xin/blog

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82150.html

相關文章

  • 閉包詳解

    摘要:再看一段代碼這樣就清晰地展示了閉包的詞法作用域能訪問的作用域將當做一個值返回執行后,將的引用賦值給執行,輸出了變量我們知道通過引用的關系,就是函數本身。 在正式學習閉包之前,請各位同學一定要確保自己對詞法作用域已經非常的熟悉了,如果對詞法作用域還不夠熟悉的話,可以先看: 深入理解閉包之前置知識---作用域與詞法作用域 前言 現在去面試前端開發的崗位,如果你的面試官也是個前端,并且不是太...

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

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

    Chiclaim 評論0 收藏0
  • Javascript 閉包詳解

    摘要:一般函數執行完畢,局部活動對象就會被銷毀,內存中僅僅保存全局作用域,但是閉包會長期駐扎在內存。我只是想通過這兩個例子來說明閉包的用處和好處。閉包會使變量始終保存在內存中,如果使用不當會增大內存消耗。 閉包特性 函數嵌套函數 函數內部可以引用外部的參數和變量 參數和變量不會被垃圾回收機制回收 閉包的作用 具體作用是有權訪問函數內部的變量,最常見的就是函數內部創建另一個函數,通過另一個函數...

    ztyzz 評論0 收藏0
  • 閉包全面詳解

    摘要:環境由閉包創建時在作用域中的任何局部變量組成。嚴格來說,閉包需要滿足三個條件訪問所在作用域函數嵌套在所在作用域外被調用閉包的形成原理先了解的垃圾回收機制會找出不再使用的變量,不再使用意味著這個變量生命周期的結束。 什么是閉包 最原始定義 閉包(closure),是指函數變量可以保存在函數作用域內,因此看起來是函數將變量包裹了起來。 //根據定義,包含變量的函數就是閉包 function...

    qylost 評論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數基礎要搞好深入淺出原型使用原型模型,雖然這經常被當作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統的類繼承還要強大。中文指南基本操作指南二繼續熟悉的幾對方法,包括,,。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家帶來幫助....(據說是阿里的前端妹子寫的) this 的值到底...

    blair 評論0 收藏0

發表評論

0條評論

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