本文簡介
點贊 + 關注 + 收藏 = 學會了
ES6
剛推出的時候,let
和 const
應該是大多數人學習 ES6
的第一個知識點。
其中 const
可以用來定義 常量 ,將不需要改變的數據定義成一個常量。
但其實在 ES6
之前我們也是有辦法定義常量的。
ES 5 創建常量
Object.defineProperty
的基礎用法
在 ES6
之前是沒有 const
的,如果需要定義常量,可以使用 Object.defineProperty
。
很多人知道 Vue2
使用 Object.defineProperty
監聽數據變化,但不一定知道 Object.defineProperty
也可以用來定義常量。
Object.defineProperty
方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,並返回此對象。
Object.defineProperty(obj, prop, descriptor)
接收3個參數
- obj: 要定義屬性的對象。
- prop: 要定義或修改的屬性的名稱或
Symbol
。 - descriptor: 要定義或修改的屬性描述符。
舉個例子
var LH = {}
Object.defineProperty(LH, 'name', {
value: '雷猴'
})
console.log(LH) // 輸出: {name: '雷猴'}
LH.name = '鯊魚辣椒'
console.log(LH) // 輸出: {name: '雷猴'}
可以將上面的代碼放到你的瀏覽器裏試試。
為什麼修改 LH.name
無效呢?因為 descriptor
除了 value
之外,還有其他屬性,比如 writable
就可以用來定義該對象是否允許被修改,默認是 false
,也就是不能修改。
所以 LH.name = '鯊魚辣椒'
修改無效。
如果將 writable
改成 true
就可以修改了
var LH = {}
Object.defineProperty(LH, 'name', {
value: '雷猴',
writable: true // 允許修改
})
console.log(LH) // 輸出: {name: '雷猴'}
LH.name = '鯊魚辣椒'
console.log(LH) // 輸出: {name: '鯊魚辣椒'}
創建常量
順著上面的思路,如果我們把 LH
改成 window
,那是不是就可以在 window
上定義一個屬性,而且該屬性是全局的,定義後在什麼地方都能調用。
Object.defineProperty(window, 'NAME', {
value: '雷猴'
})
console.log(NAME) // 輸出: 雷猴
NAME = '鯊魚辣椒'
console.log(NAME) // 輸出: 雷猴
window.NAME = '蟑螂惡霸'
console.log(NAME) // 輸出: 雷猴
不管如何修改,NAME
都是最開始定義的值。
常量居然可以修改值?
上面創建的常量,value
是一個基礎數據類型的值。如果換成引用類型的值,那內容是可以修改的。
Object.defineProperty(window, 'NAME', {
value: {
nickname: '雷猴'
}
})
console.log(NAME)
NAME.nickname = '鯊魚辣椒'
console.log(NAME)
原因是,常量鎖定的是定義時所指向的內存地址。
定義基礎數據類型時,內存地址直接指向那個值。但定義引用類型時,內存地址存的是引用地址。所以常量的定義指的是引用地址不能修改。
兼容性
使用 Object.defineProperty
定義常量時需要注意兼容性
推薦閱讀
《Object.defineProperty也能監聽數組變化?》
點贊 + 關注 + 收藏 = 學會了
點贊 + 關注 + 收藏 = 學會了