閉包、符號、WeakMap、類別私有欄位和代理程式是一些可用來在 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 傳回一個具有方法 getValue 和 setValue 的物件。這些方法可以檢索或更改在父函數中聲明的 privateVariable 的值,因為它們可以存取它。如果您嘗試從函數外部存取 privateVariable,則會發生參考錯誤。
使用符號資料型別是建立私有變數的第二種方法。符號可以用作屬性鍵,因為它們是不同的非字串標識符。由於它們是唯一的,因此外部程式無法輕鬆存取或更改它們。
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,所以無法使用點表示法來取得屬性的值,但可以使用方括號表示法透過物件存取它。
WeakMaps 可以用來作為建構私有變數的第三種方法。 JavaScript 引擎僅弱引用 WealMap 中的鍵值對,這可讓您將物件與鍵連結。這使得錯誤地維護對私有變數的引用變得更加困難,因為如果沒有對該鍵的其他引用,垃圾收集器將銷毀該鍵值對。
<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 的 WeakMap,用於保存物件的私有變數。 get() 方法用於在使用 set() 方法將私有變數連結到物件後取得該私有變數。但是,私有變數無法從物件形成的範圍之外訪問,因為只有當您擁有對該物件的參考時才能存取它。
使用物件導向的類別語法也可以用來建立私有變數。 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 的類別。如果類別外部的方法嘗試存取只能由類別內部的方法存取的私有變量,則會發生參考錯誤。
最後,使用 Proxy 物件是建構私有變數的另一種選擇。可用於攔截或更改其他物件行為的物件稱為代理。您可以透過將物件封裝在代理程式中來建立只能由具有代理程式的程式碼存取的私有變數。
<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 方法的處理程序的代理。這些方法可以檢索或更改在代理外部定義的私有變數的值並可以存取它。然而,由於引用錯誤,私有變數將無法從代理外部存取。
以上是如何在 JavaScript 中建立私有變數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!