閉包(Closure)基礎分析

来源:http://www.cnblogs.com/asheng2016/archive/2017/08/02/7277097.html
-Advertisement-
Play Games

閉包(Closure) 本文聚焦於回答2個問題: 1. 在全局作用域中,如何讀取函數內部的局部變數? 2. 在全局作用域中,如何修改函數內部的局部變數? 變數作用域 JavaScript語言的作用域,一句話概括就是:內層函數可以訪問外層函數的變數,而外層函 數不可以訪問內層函數的變數。 在內層函數中 ...


閉包(Closure)

本文聚焦於回答2個問題:

  1. 在全局作用域中,如何讀取函數內部的局部變數?
  2. 在全局作用域中,如何修改函數內部的局部變數?

變數作用域

JavaScript語言的作用域,一句話概括就是:內層函數可以訪問外層函數的變數,而外層函
數不可以訪問內層函數的變數。

在內層函數中定義的變數如果沒使用var關鍵詞,則該變數變為全局變數。通過這種方法定義
的全局變數,要在此函數執行後才有效。請看下麵代碼:

function outer() {
    n = 820;

    function inner() {
        he = 835;
    }

    return inner;
}

// console.log(n); 
// n is not defined
// 上面的錯誤會打斷程式執行,如要測試下麵的代碼,需註釋掉上面的代碼

outer();
console.log(n); // 820

// console.log(he);
// n is not defined

(outer())();
console.log(he); // 835

如何從外部讀取局部變數

通過閉包可以實現在全局作用域中訪問函數內部變數。

function outer() {
    var n = 820;

    function inner() {
        return n;
    }

    return inner;
}

var k = (outer())();
console.log(k); // 820

outer()函數執行一次,將返回inner()函數的引用,再執行一次inner()
函數,就成功的把局部變數n返回出來。從而實現從外部讀取內部變數。

如何從外部修改局部變數

通過閉包可以實現在全局作用域中修改函數內部變數。

var n = "hello";

function outer() {
    var n = 820;

    function get() {
        return n;
    }

    function inc() {
        n++;
    }

    return {
        n: n,
        get: get,
        inc: inc
    };
}

var result = outer();

console.log( result.n ); // 820
console.log( result.get() ); // 820

result.inc();
console.log( result.get() ); // 821
result.inc();
console.log( result.get() ); // 822

console.log( result.n ); // 820

outer()函數返回一個對象,這個對象有1個屬性,2個方法。正常情況下一個
函數調用完畢,其內部的變數將會被垃圾回收機制(garbage collection)回收。
也就是說這些變數已經不存在記憶體中,也沒有辦法讀取這些變數的值,更沒法修改。

但是,我們把outer()函數的返回值賦給了一個全局變數,全局變數是始終存在
記憶體中的,而這個全局變數result又使用到了outer()函數的局部變數,所以
outer()函數的局部變數,不會被清除,將一直保存在記憶體中。

因此,只要我們執行一次result.inc(), outer()函數裡面的n就會增加1。
而我們通過result.get()就可以訪問到outer()函數裡面的n

要註意result.n的值始終是820,這裡面的820只是n變數的一個副本,一旦
outer()函數執行完畢,result.n就和n沒有關係了。

註意事項

由於閉包會使得函數中的變數都被保存在記憶體中,記憶體消耗很大,所以不能濫用閉包
,否則會造成網頁的性能問題。

參考資料

http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近跑來打數據結構,於是我決定搞一發可持久化,然後發現……一發不可收啊…… 對於可持久化數據結構,其最大的特征是“歷史版本查詢”,即可以回到某一次修改之前的狀態,並繼續操作;而這種“歷史版本查詢”會衍生出其他一些強大的操作。 今天,我們主要講解可持久化線段樹。其實,它的另外一個名字“主席樹”似乎更加 ...
  • 1. php中字元串可以用哪三種方法定義: 單引號、雙引號、定界符 2. 定義常量和靜態常量的語法是: define(‘常量名’,’常量值’) static $var 3. 用php列印出昨天的時間,格式是2006-05-10 22:21:21: date_default_timezone_set( ...
  • 最近接觸了不少次下載http網頁和文件的程式,突然對其原理很感興趣,又碰巧看到了http協議基於socket,這更是讓我激動不已。畢竟之前花了很長時間接觸socket這個實用的底層協議,做了小型聊天室來練習,然而卻不知道生活中有什麼具體的實例是由socket完成的。於是乎,查閱了各路筆記和文檔,再加... ...
  • 迭代器和生成器是函數中的一大重點,務必掌握,何為迭代?何為迭代器? ...
  • 基於Spring Cloud的微服務構建學習-1 基礎知識 什麼是微服務架構 微服務是系統架構上的一種設計風格,它的主旨是將一個原本獨立的系統拆分成多個小型服務,這些小型服務都在各自獨立的進程中運行,服務之間通過基於HTTP的RESTful API進行通信協議。 每個微服務都維護者自身的數據存儲、業 ...
  • 分散式系統中主要的問題就是如何保持節點狀態的一致性,不論發生任何failure,只要集群中大部分的節點可以正常工作,則這些節點具有相同的狀態,保持一致,在client看來相當於一臺機器。 一致性問題本質就是replicated state machines,即所有結點都從同一個state出發,都經過 ...
  • HashMap 簡介 Java為數據結構中的映射定義了一個介面java.util.Map,此介面主要有四個常用的實現類,分別是HashMap、Hashtable、LinkedHashMap和TreeMap,類繼承關係如下圖所示: 下麵針對各個實現類的特點做一些說明: (1) HashMap:它根據鍵 ...
  • 網頁中插入圖像 ================== 針對普通類圖片 IMG vs CSS background image 使用IMG 圖像是內容的一部分 網站logo如 "支付寶註冊頁面" 、圖表、照片人物等與上下文有關的,需要使用atl屬性 利於搜索引擎、屏幕閱讀器 對於輪播圖等需要JavaS ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...