Linux中國

JavaScript 閉包實踐

在《JavaScript 如此受歡迎的 4 個原因》中,我提到了一些高級 JavaScript 概念。在本文中,我將深入探討其中的一個概念: 閉包 closure

根據 Mozilla 開發者網路(MDN),「閉包是將一個函數和對其周圍的狀態(詞法環境)的引用捆綁在一起(封閉)的組合。」簡而言之,這意味著在一個函數內部的函數可以訪問其外部(父)函數的變數。

為了更好地理解閉包,可以看看作用域及其執行上下文。

下面是一個簡單的代碼片段:

var hello = "Hello";

function sayHelloWorld() {
    var world = "World";
    function wish() {
        var year = "2021";
        console.log(hello + " " + world + " "+ year);
    }
    wish();
}
sayHelloWorld();

下面是這段代碼的執行上下文:

![JS 代碼的執行上下文](/data/attachment/album/202102/21/163151d6tma7k3pp2lgz43.png "Execution context for JS code")

每次創建函數時(在函數創建階段)都會創建閉包。每個閉包有三個作用域。

  • 本地作用域(自己的作用域)
  • 外部函數範圍
  • 全局範圍

我稍微修改一下上面的代碼來演示一下閉包:

var hello = "Hello";

var sayHelloWorld = function() {
    var world = "World";
    function wish() {
        var year = "2021";
        console.log(hello + " " + world + " "+ year);
    }
    return wish;
}
var callFunc = sayHelloWorld();
callFunc();

內部函數 wish() 在執行之前就從外部函數返回。這是因為 JavaScript 中的函數形成了閉包

  • sayHelloWorld 運行時,callFunc 持有對函數 wish 的引用。
  • wish 保持對其周圍(詞法)環境的引用,其中存在變數 world

私有變數和方法

本身,JavaScript 不支持創建私有變數和方法。閉包的一個常見和實用的用途是模擬私有變數和方法,並允許數據隱私。在閉包範圍內定義的方法是有特權的。

這個代碼片段捕捉了 JavaScript 中閉包的常用編寫和使用方式:

var resourceRecord = function(myName, myAddress) {
    var resourceName = myName;
    var resourceAddress = myAddress;
    var accessRight = "HR";
    return {
        changeName: function(updateName, privilege) {
            // only HR can change the name
            if (privilege === accessRight ) {
                resourceName = updateName;
                return true;
            } else {
                return false;
            }
        },  
        changeAddress: function(newAddress) {
            // any associate can change the address
            resourceAddress = newAddress;          
        },  
        showResourceDetail: function() {
            console.log ("Name:" + resourceName + " ; Address:" + resourceAddress);
        }
    }
}
// Create first record
var resourceRecord1 = resourceRecord("Perry","Office");
// Create second record
var resourceRecord2 = resourceRecord("Emma","Office");
// Change the address on the first record
resourceRecord1.changeAddress("Home");
resourceRecord1.changeName("Perry Berry", "Associate"); // Output is false as only an HR can change the name
resourceRecord2.changeName("Emma Freeman", "HR"); // Output is true as HR changes the name
resourceRecord1.showResourceDetail(); // Output - Name:Perry ; Address:Home
resourceRecord2.showResourceDetail(); // Output - Name:Emma Freeman ; Address:Office

資源記錄(resourceRecord1resourceRecord2)相互獨立。每個閉包通過自己的閉包引用不同版本的 resourceNameresourceAddress 變數。你也可以應用特定的規則來處理私有變數,我添加了一個誰可以修改 resourceName 的檢查。

使用閉包

理解閉包是很重要的,因為它可以更深入地了解變數和函數之間的關係,以及 JavaScript 代碼如何工作和執行。

via: https://opensource.com/article/21/2/javascript-closures

作者:Nimisha Mukherjee 選題:lujun9972 譯者:wxy 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    這個站點使用 Akismet 來減少垃圾評論。了解你的評論數據如何被處理

    More in:Linux中國

    Linux中國

    捐贈 Let's Encrypt,共建安全的互聯網

    隨著 Mozilla、蘋果和谷歌對沃通和 StartCom 這兩家 CA 公司處罰落定,很多使用這兩家 CA 所簽發證書的網站紛紛尋求新的證書籤發商。有一個非盈利組織可以為大家提供了免費、可靠和安全的 SSL 證書服務,這就是 Let's Encrypt 項目。現在,它需要您的幫助
    Linux中國

    關於Linux防火牆iptables的面試問答

    Nishita Agarwal是Tecmint的用戶,她將分享關於她剛剛經歷的一家公司(印度的一家私人公司Pune)的面試經驗。在面試中她被問及許多不同的問題,但她是iptables方面的專家,因此她想分享這些關於iptables的問題和相應的答案給那些以後可能會進行相關面試的人。 所有的問題和相應的答案都基於Nishita Agarwal的記憶並經過了重寫。 嗨,朋友!我叫Nishita Agarwal。我已經取得了理學學士學位,我的專業集中在UNIX和它的變種(BSD,Linux)。它們一直深深的吸引著我。我在存儲方面有1年多的經驗。我正在尋求職業上的變化,並將供職於印度的P
    Linux中國

    Lets Encrypt 已被所有主流瀏覽器所信任

    旨在讓每個網站都能使用 HTTPS 加密的非贏利組織 Lets Encrypt 已經得了 IdenTrust的交叉簽名,這意味著其證書現在已經可以被所有主流的瀏覽器所信任。從這個裡程碑事件開始,訪問者訪問使用了Lets Encrypt 證書的網站不再需要特別配置就可以得到 HTTPS 安全保護了。 Lets Encrypt 的兩個中級證書 ...