如何在 JavaScript 中建立私有變數?


閉包、符號、弱對映、類私有欄位和代理是用於在 JavaScript 中建立私有變數的一些技術。每種技術都有其優點和缺點,因此選擇最適合您需求的技術至關重要。

與許多其他程式語言一樣,JavaScript 具有私有和公有變數的概念。私有變數只能由屬於同一作用域的程式碼訪問和修改,而公有變數可以由任何程式碼訪問和修改。讓我們看看在 JavaScript 中建立私有變數的不同技術。

使用閉包

閉包方法是建立 JavaScript 中私有變數的一種方法。如果一個函式即使在其父函式已完成並返回後仍然可以訪問其父函式作用域中定義的變數,則該函式就是一個閉包。我們可以在函式內部定義一個變數,使其成為一個私有變數,只能由該函式內部的程式碼訪問。

示例

<html>
<body>
   <div id="demo"></div>
   <script>
      function createPrivateVariable() {
         let privateVariable = "This is a private variable";
         return {
            getValue: function () {
               return privateVariable;
            },
            setValue: function (value) {
               privateVariable = value;
            },
         };
      }
      let privateVar = createPrivateVariable();
      document.getElementById("demo").innerHTML = privateVar.getValue();
   </script>
</body>
</html>

上面示例中的 createPrivateVariable 函式返回一個具有 getValuesetValue 方法的物件。這些方法可以檢索或更改在父函式中宣告的 privateVariable 的值,因為它們可以訪問它。如果您嘗試從函式外部訪問 privateVariable,則會發生引用錯誤。

使用 Symbol 資料型別

使用 Symbol 資料型別是建立私有變數的第二種方法。符號可以作為屬性鍵使用,因為它們是唯一的、非字串的識別符號。由於它們是唯一的,因此外部程式不容易訪問或修改它們。

let privateVariable = Symbol();
let obj = {
   [privateVariable]: "This is a private variable"
};
console.log(obj[privateVariable]);

示例

我們可以如下使用上述程式碼:

<html>
<body>
   <div id="demo"></div>
   <script>
      let privateVar = Symbol();
      let obj = {
         [privateVar]: "This is a private variable"
      };
      Object.defineProperty(obj, 'getValue', {
         get: function() {
            return obj[privateVar];
         }
      });
      document.getElementById("demo").innerHTML = obj.getValue;
   </script>
</body>
</html>

在此示例中,已定義了一個名為 privateVariable 的 Symbol,並將其用作物件的屬性鍵。由於它是一個 Symbol,因此無法使用點表示法獲取屬性的值,但可以使用方括號表示法透過物件訪問它。

使用弱對映

弱對映可用作構造私有變數的第三種方法。JavaScript 引擎僅弱引用弱對映中的鍵值對,這允許您將一個物件與一個鍵關聯。由於垃圾回收器將在沒有其他對鍵的引用時銷燬鍵值對,因此這使得意外地維護對私有變數的引用變得更加困難。

示例

<html>
<body>
   <div id="demo"></div>
   <script>
      let privateVariables = new WeakMap();
      let obj = {};
      privateVariables.set(obj, "This is a private variable");
      document.getElementById("demo").innerHTML = privateVariables.get(obj);
   </script>
</body>
</html>

在此示例中,我們建立了一個名為 privateVariables 的弱對映,用於儲存物件的私有變數。一旦使用 set() 方法將物件與鍵關聯,就可以使用 get() 方法獲取私有變數。但是,私有變數只能在您擁有對物件的引用時才能訪問,因此無法從建立物件的範圍之外訪問它。

使用面向物件的類語法

面向物件的類語法的使用也可以用於建立私有變數。JavaScript 的 class 關鍵字使我們能夠定義類,類充當物件的模板。類可以使用變數名前面的 # 符號來定義變數以生成私有變數;這是一個實驗性特性,表示一個私有變數。由於它目前沒有得到廣泛的支援,因此不建議在生產程式碼中使用此特性。

示例

<html>
<body>
   <p id="output"></p>
   <script>
      class MyClass {
         #privateVariable = "This is a private variable";
         getValue() {
            return this.#privateVariable;
         }
         setValue(value) {
            this.#privateVariable = value;
         }
      }
      let obj = new MyClass();
      document.getElementById("output").innerHTML = obj.getValue(); // "This is a private variable"
      obj.setValue("New value");
      document.getElementById("output").innerHTML = obj.getValue(); // "New value"
   </script>
</body>
</html>

在此示例中,使用私有變數 #privateVariable、getValue 和 setValue 構造了一個名為 MyClass 的類。如果類外部的方法嘗試訪問只能由類內部方法訪問的私有變數,則會發生引用錯誤。

使用代理物件

最後,使用代理物件是構造私有變數的另一種選擇。代理是可以用來攔截或修改其他物件行為的物件。您可以透過將物件封裝在代理中來建立一個私有變數,該變數只能由擁有該代理的程式碼訪問。

示例

<html>
<body>
   <div id="demo"></div>
   <script>
      let privateVariable = "This is a private variable-proxy obj.";
      let handler = {
         get: function (target, name) {
            if (name === "privateVariable") {
               return privateVariable;
            }
         },
         set: function (target, name, value) {
            if (name === "privateVariable") {
               privateVariable = value;
            }
         },
      };
      let obj = new Proxy({}, handler);
      document.getElementById("demo").innerHTML = obj.privateVariable;
   </script>
</body>
</html>

在此示例中,已構建了一個帶有處理程式(包含 getter 和 setter 方法)的代理。這些方法可以檢索或更改在代理外部定義並可以訪問它的私有變數的值。但是,由於引用錯誤,私有變數將無法從代理外部訪問。

更新於:2023-03-02

5K+ 閱讀量

啟動您的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.