JavaScript最近有不少改進,新的語法和特性一直在添加。但有些事情不會改變,全部的東西仍然是一個對象,幾乎全部的東西均可以在運行時改變,也沒有公有/私有屬性的概念。可是咱們能夠用一些技巧來改變這些,在這篇文章中,我將研究實現私有屬性的各類方法javascript
JavaScriopt 在 2015 年引入了「類」這種你們都熟悉的面向對象方法,基於 C 語言的經典語言 Java 和 C# 就提供這種方法。不過很快你們就發現這些類並非習慣的那樣 —— 他們沒有控制訪問的屬性修飾符,並且全部屬性都必須定義在函數中。java
那麼,咱們該如何保護那些不該該在運行期間被修改的數據呢?先來看一些辦法。函數
這篇文章中我會使用一個建立圖形的類做爲示例。它的寬度和高度只能高度只能在初始化時設置,同時提供一個用於獲取面積的屬性。這些示例中用到了 get 關鍵字,你能夠在個人文章 Getter 和 Setter 中瞭解到這一知識點this
第一個方法是使用特定的命名來表示屬性應該被視爲私有,這是最成熟的方法。其常見做法是給屬性名前綴一個下劃線(好比 _count)。但這種方法不能阻止值被訪問或被修改,它依賴於不一樣開發者之間的共識,公認這個值應該被禁止訪問。spa
class Shape { constructor(width, height) { this._width = width; this._height = height; } get area() { return this._width * this._height; } } const square = new Shape(10, 10); console.log(square.area); // 100 console.log(square._width); // 10
使用 WeakMap 保存私有值的方法限制性會稍微強一些。雖然這個方法仍然不能阻止訪問數據,但它把私有值與用戶交互對象隔離開了。在這種技巧中,咱們把擁有私有屬性的對象實例做爲 WeakMap 的鍵,並使用一個函數(咱們稱爲 internal)來建立或返回一個存儲全部私有屬性值的對象。這種技術的優勢是在枚舉對象屬性或者使用 JSON.stringify 時不會把私有屬性顯示出來,但它依賴 WeakMap,而 WeakMap 對象類的做用域外仍然能夠被訪問到,也能夠進行操做。code