本文轉載自:
如何在 ES5 環境下實現一個const
https://juejin.im/post/5ce3b2d451882533287a767f
const 實現原理
由於ES5環境沒有block的概念,所以是無法百分百實現const,只能是掛載到某個對象下,要麼是全局的window,要麼就是自定義一個object來當容器
var __const = function __const (data, value) {
window.data = value // 把要定義的data掛載到window下,並賦值value
Object.defineProperty(window, data, { // 利用Object.defineProperty的能力劫持當前對象,並修改其屬性描述符
enumerable: false,
configurable: false,
get: function () {
return value
},
set: function (data) {
if (data !== value) { // 當要對當前屬性進行賦值時,則拋出錯誤!
throw new TypeError('Assignment to constant variable.')
} else {
return value
}
}
})
}
__const('a', 10)
console.log(a)
delete a
console.log(a)
for (let item in window) { // 因爲const定義的屬性在global下也是不存在的,所以用到了enumerable: false來模擬這一功能
if (item === 'a') { // 因爲不可枚舉,所以不執行
console.log(window[item])
}
}
a = 20 // 報錯
Vue目前雙向綁定的核心實現思路就是利用Object.defineProperty對get跟set進行劫持,監聽用戶對屬性進行調用以及賦值時的具體情況,從而實現的雙向綁定~~
屬性描述符:
對象裏目前的屬性描述符有兩種:
數據描述符:具有值的屬性
存取描述符:由getter與setter函數對描述的屬性
描述符功能:
數據描述符與存取描述符皆可修改:
configurable:當前對象元素的屬性描述符是否可改,是否可刪除
enumerable:當前對象元素是否可枚舉
唯有數據描述符可以修改:
value: 當前對象元素的值
writable:當前對象元素的值是否可修改
唯有存取描述符可以修改:
get:讀取元素屬性值時的操作
set:修改元素屬性值時的操作
描述符可同時具有的鍵值:
configurable enumerable value writable get set
數據描述符 Yes Yes Yes Yes No No
存取描述符 Yes Yes No No Yes Yes