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

資訊專欄INFORMATION COLUMN

JavaScript之閉包

huashiou / 1458人閱讀

摘要:以上描述,全部符合閉包的描述,那這就是閉包。二執(zhí)行過程之前的文章講了函數(shù)的執(zhí)行上下文棧,變量對象,作用域鏈等內(nèi)容,接下來通過閉包代碼回顧代碼是怎么樣的執(zhí)行過程。將活動對象壓入作用域鏈頂端。函數(shù)執(zhí)行結束,彈出執(zhí)行上下文棧。

本文一共  1300 字,讀完只需  5 分鐘
概述

閉包, 可以說是每個前端工程師都聽說的一個詞,咋一看很難從字面上去理解,從而給人留下了閉包是一個重要又難以理解的概念。

但是,閉包在 JS 代碼可以說是隨處可見,閉包也只是計算機領域的一個概念而已,它的存在是因為 JS 的一些語言特性,比如:函數(shù)式語言執(zhí)行上下文執(zhí)行上下文棧,作用域鏈詞法作用域

執(zhí)行上下文:Execution Context
執(zhí)行上下文棧:Execution Context Stack
作用域鏈:Scope Chain
作用域:Scope

本篇文章,將先給結論,到底什么是閉包,再來分析產(chǎn)生閉包的過程和原因。

一、什么是閉包
當函數(shù)記住并訪問所在詞法作用域的自由變量時,就產(chǎn)生了閉包,即使函數(shù)是在當前詞法作用域外執(zhí)行。
--《你不知道的 JavaScript》

來段經(jīng)典的閉包代碼:

function outter() {
    var a = 123;
    
    function inner() {
        console.log(a);
    }
    return inner;
}

var foo = outter();
foo();  // 123

內(nèi)部函數(shù) inner 記住了它被定義時的詞法作用域,也就是 outter 的函數(shù)作用域,并訪問了該作用域里的自由變量 a, 同時,inner 函數(shù)作用返回值,在外部作用域中被執(zhí)行。

以上描述,全部符合閉包的描述,那這就是閉包

二、執(zhí)行過程

之前的文章講了函數(shù)的執(zhí)行上下文棧,變量對象,作用域鏈等內(nèi)容,接下來通過閉包代碼回顧代碼是怎么樣的執(zhí)行過程。

function outter() {
    var a = 123;
    
    function inner() {
        console.log(a);
    }
    return inner;
}

var foo = outter();
foo();  // 123

進入全局代碼的執(zhí)行上下文,全局上下文被壓入執(zhí)行上下文棧。

ECStack = [
        globalContext
    ];

全局上下文創(chuàng)建全局變量對象,創(chuàng)建 this 并指向全局上下文。

globalContext = {
    VO: global,
    scope: [global.VO],
    this: global
}

全局上下文初始化時,outter 函數(shù)被創(chuàng)建,建立作用域鏈,復制 Scope 屬性到 outter 函數(shù)的內(nèi)部屬性[[scope]]

  outter.[[scope]] = [     
    globalContext.VO
  ];

執(zhí)行 outter 函數(shù),創(chuàng)建 outter 函數(shù)執(zhí)行上下文,將 outter 上下文壓入執(zhí)行上下文棧。

ECStack = [
        globalContext,
        outterContext
    ];

初始化 outter 函數(shù)執(zhí)行上下文,用 arguments 創(chuàng)建活動對象,加入形參、函數(shù)聲明、變量聲明。將活動對象壓入 outter 作用域鏈頂端。

outterContext = {
    AO: {
        arguments: {
            a: undefined,
        }
        length: 1
    },
    scope: undefined,
    inner: reference to function inner(){}
    Scope: [AO, globalContext.VO],
    this: undefined
}

outter 執(zhí)行完畢,接著執(zhí)行 outter 返回的被變量引用的函數(shù) inner;

ECStack = [
        globalContext,
        innerContext
    ];

inner 函數(shù)初始化,過程和第4步一樣。

innerContext = {
        AO: {
            arguments: {
                length: 0
            }
        },
        Scope: [AO, outterContext.AO, globalContext.VO],
        this: undefined
    }

inner 執(zhí)行,沿著作用域鏈查找變量 a, 打印 a 值。

inner 函數(shù)執(zhí)行結束,彈出執(zhí)行上下文棧。

ECStack = [
        globalContext
    ];

在這個過程中,第 5 步,outter 已經(jīng)執(zhí)行結束,執(zhí)行上下文按理來說已經(jīng)被銷毀,內(nèi)部函數(shù) inner 怎么還能訪問 outter 作用域的變量呢。

正是由于閉包,inner 引用了它所在詞法作用域的自由變量 a,inner 的作用域鏈中仍然是完整的, 盡管 inner 在其他地方執(zhí)行,還是返回了正確結果。

三、函數(shù)式語言

閉包中,一個很重要的特點就是,內(nèi)部函數(shù)作為一個數(shù)據(jù)被返回。這是由于 JS 是函數(shù)式語言,函數(shù)可以作為參數(shù)傳遞進函數(shù),也可以作為一個數(shù)據(jù)返回。函數(shù)的嵌套構成了作用域的嵌套,也就有了作用域鏈。

由于函數(shù)具有作用域,且變量的尋找具有 “遮蔽效應”(從內(nèi)到外,找到第一個就停止),使得局部作用域的變量對于外部作用域是不可見的,于是函數(shù)就有了封閉性,所以我們拿函數(shù)來包裹封裝私有變量,同時也有了閉包。

四、自由變量
自由變量是指在函數(shù)中使用的,但既不是函數(shù)參數(shù)也不是函數(shù)的局部變量的變量。
function outter() {
    var a = 123;
    
    function inner() {
        console.log(a);
    }
    return inner;
}

var foo = outter();
foo();  // 123

對于 inner 函數(shù)而言,變量 a, 不是它的函數(shù)參數(shù),也不是它的局部變量,a 就是自由變量。

五、閉包的用處和缺點

從閉包的特點可以看出,自由變量保存在了內(nèi)存中,并能間接訪問。

那么閉包的作用就是:

隱藏私有變量,解決變量命名空間污染的問題。

缺點
如果閉包過多,變量常駐內(nèi)存,肯定會占用大量內(nèi)存空間。

總結

由于 JS 是函數(shù)式語言,當函數(shù)記住并訪問所在詞法作用域的自由變量時,就產(chǎn)生了閉包,即使函數(shù)是在當前詞法作用域外執(zhí)行。

閉包在 JS 代碼中非常常見,不必把它想得太玄乎。

歡迎關注我的個人公眾號“謝南波”,專注分享原創(chuàng)文章。

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

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

相關文章

  • JavaScript深入閉包

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

    caige 評論0 收藏0
  • 【進階2-3期】JavaScript深入閉包面試題解

    摘要:閉包面試題解由于作用域鏈機制的影響,閉包只能取得內(nèi)部函數(shù)的最后一個值,這引起的一個副作用就是如果內(nèi)部函數(shù)在一個循環(huán)中,那么變量的值始終為最后一個值。 (關注福利,關注本公眾號回復[資料]領取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實戰(zhàn)、面試指導) 本周正式開始前端進階的第二期,本周的主題是作用域閉包,今天是第8天。 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了...

    alanoddsoff 評論0 收藏0
  • 【進階2-2期】JavaScript深入從作用域鏈理解閉包

    摘要:使用上一篇文章的例子來說明下自由變量進階期深入淺出圖解作用域鏈和閉包訪問外部的今天是今天是其中既不是參數(shù),也不是局部變量,所以是自由變量。 (關注福利,關注本公眾號回復[資料]領取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實戰(zhàn)、面試指導) 本周正式開始前端進階的第二期,本周的主題是作用域閉包,今天是第7天。 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進階計...

    simpleapples 評論0 收藏0
  • 進擊JavaScript(三)玩轉(zhuǎn)閉包

    摘要:為了更好的理解,在閱讀此文之前建議先閱讀上一篇進擊之詞法作用域與作用域鏈什么是閉包閉包的含義就是閉合,包起來,簡單的來說,就是一個具有封閉功能與包裹功能的結構。在中函數(shù)構成閉包。 為了更好的理解,在閱讀此文之前建議先閱讀上一篇《進擊JavaScript之詞法作用域與作用域鏈》 1.什么是閉包 閉包的含義就是閉合,包起來,簡單的來說,就是一個具有封閉功能與包裹功能的結構。所謂的閉包就是...

    cyixlq 評論0 收藏0
  • 【譯】理解JavaScript閉包

    摘要:當面試中讓我解釋一下閉包時我懵逼了。這個解釋開始可能有點晦澀,讓我們抽絲剝繭摘下閉包的真面目。此文不詳述作用域有專門的主題闡述,不過作用域是理解閉包原理的基礎。這才是閉包的真正便利之處。閉包使用不當就會很坑。 原文鏈接 為什么深度學習JavaScript? JavaScript如今是最流行的編程語言之一。它運行在瀏覽器、服務器、移動設備、桌面應用,也可能包括冰箱。無需我舉其他再多不相干...

    岳光 評論0 收藏0
  • 【前端工程師手冊】JavaScript閉包

    摘要:閉包確實是一個說爛了的概念,校招社招都會被問到,今天總結一番。先下定義,閉包是函數(shù)和該函數(shù)的詞法作用域的組合。在這個栗子里,函數(shù)以及它對變量的引用就構成了閉包。閉包和作用域?qū)τ陂]包和作用域的關系,我的理解是閉包其實就是作用域的延伸。 閉包確實是一個說爛了的概念,校招社招都會被問到,今天總結一番。先下定義,閉包是函數(shù)和該函數(shù)的詞法作用域的組合。其實這個定義是比較教條的,可以直白的理解為閉...

    CarlBenjamin 評論0 收藏0

發(fā)表評論

0條評論

huashiou

|高級講師

TA的文章

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