作為前端工程師,有些朋友對 Object.defineProperty 和 Proxy 有一定的認識,卻不瞭解 JavaScript 中的存儲器(setter、getter),誤以為這又是一個新的語法。
其實,存儲器語法早在 ES5 中就被引入,本期文章就對存儲器進行討論。
從例子出發
以姓名為例,分別存放姓、名:
如果需要獲取全名,或通過全名來設置姓和名,很多朋友會藉助方法實現。
上述代碼中,新增了兩個方法來實現全名的讀寫,通過調用函數的形式來使用。
而通過 ES5 引入的存取器,可以更優雅地實現。
存取器屬性
使用存取器屬性很簡單,使用 get 和 set 關鍵字,後接一個同名函數。
上述代碼中,定義了 fullname 的 getter 和 setter。在使用時,只需像普通屬性一樣使用。
那麼,這個存取器屬性和普通屬性有什麼異同呢?
數據屬性和存取器屬性
上文所說的普通屬性,準確來說,是叫數據屬性。顧名思義就是存放數據的屬性。
在 ECMAScript 存在兩種屬性,一種是普遍使用的數據屬性,一種是上文所說的存取器屬性。
1. 數據屬性
我們知道,除了可以使用普通的 key-value 的方式來定義對象的數據屬性。
還可以使用 Object.defineProperty 進行定義。
上述代碼中,定義了 obj 中的 name 屬性,它具有可寫、可配置、可枚舉、值是 前端專欄 的特性。
2. 存取器屬性
同樣,存取器屬性作為屬性,也可以像數據屬性一樣直接定義,但需要 get 和 set 關鍵字配合。
另外,同樣也可以通過 Object.defineProperty 進行配置。
3. 異同
觀察數據屬性和訪問器屬性中,使用 Object.defineProperty 定義的代碼。相同的是,它們都含有 [[Configurable]] 和 [[Enumerable]] 特性。
而區別在於:
- 數據屬性含有 [[Writable]] 和 [[Value]] 特性
- 訪問器屬性含有 [[Get]] 和 [[Set]] 特性。
如下表所示,綠色代表該屬性下可存在的特性,紅色代表不可存在的特性。
注意,[[Writable]]、[[Value]] 和 [[Get]]、[[Set]] 之間是互斥關係。因為一個屬性,它不能既屬於數據屬性,也屬於訪問器屬性。如果在 Object.defineProperty 中同時定義互斥特性會拋出異常。
結語
以上就是對 JavaScript 的存取器的討論,希望能幫助大家理解 JavaScript 中的存取器。
你的點贊和轉發,是我創作的動力!
關鍵字: 存取器屬性 ECMAScript JavaScript