最近看到一個面試題——用ES5實現const。作為JS初學者的筆者知道在ES6中有const命令,可以用來聲明常量,一旦聲明,常量的值就不可改變。例如:
1 |
const Pi = 3.1415; |
但是讓我困惑的是,怎么才能使用ES5來實現const呢?說到這里我就想起了下半年···中美合拍···兩開花···啊不對!!是想起了最近在學習Vue框架,而Vue在實現響應式原理時使用到了Object.defineProperty()
方法,該方法可以定義對象屬性的數據描述符,比如configurable、writable、enumerable等等,通過這些描述符就可以設置對象屬性是否可讀可寫可配置可枚舉,進而就可以實現類似定義常量的功能。
Object.defineProperty()
方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。語法如下:
Object.defineProperty(obj, prop, descriptor)
其中descriptor
代表將被定義或修改的屬性描述符。屬性描述符有兩種主要形式:數據描述符和存取描述符。本文只討論數據描述符,數據描述符有以下選項:
configurable
當且僅當該屬性的 configurable 為 true 時,該屬性
描述符
才能夠被改變,同時該屬性也能從對應的對象上被刪除。默認為 false。enumerable
當且僅當該屬性的
enumerable
為true
時,該屬性才能夠出現在對象的枚舉屬性中。默認為 false。value
該屬性對應的值。可以是任何有效的 JavaScript 值(數值,對象,函數等)。默認為 undefined。
writable
當且僅當該屬性的
writable
為true
時,value
才能被賦值運算符改變。默認為 false。
此時我們設想,當我們講對象屬性中的writable設為false的時候,該屬性是只讀的,就能滿足我們對常量的要求了。
1 |
var _const = {}; |
但此時,我們只要修改屬性的數據描述符來修改屬性值,依然可以對屬性值進行修改:
1 |
var _const = {}; |
如此我們就需要將configurable設置為false,這樣屬性就不可配置了。
1 |
var _const = {}; |
但是configurable
特性表示對象的屬性是否可以被刪除,以及除writable
特性外的其他特性是否可以被修改。所以writable特性依舊可以修改,僅限於由true改為false,不能由false改為true。並且value值的設置也不會應此受到影響,則會出現下述情況:
1 |
var _const = {}; |
因此,通過Object.defineProperty()
方法,使用屬性的數據描述符,可以定義一個命名空間,將常量封裝在命名空間里面。由於屬性描述符默認為false,所以可以這樣定義:
1 |
var _const = {}; |
參考鏈接:
3.ECMAScript 6 入門-阮一峰