擱置了幾天我仍是決定再次重寫!html
下邊咱們來具體聊聊先從defineProperty開始提及vue
//defineproperty 有個定義object屬性的功能,應該沒幾我的用,由於相對於obj.a = 1這種方式簡直不能再難用。 //一般咱們定義obj屬性 let obj = { a:1 } obj.b = 2 obj['c'] = 3 console.log(obj)//{a: 1, b: 2,c: 3} Object.defineProperty(obj,'d',{ value: 4 }) console.log(obj)//{a: 1, b: 2,c: 3,d:4} //defineProperty能夠定義對象屬性 //也能夠修改 Object.defineProperty(obj,'b',{ value: 5 }) console.log(obj)//{a: 1, b: 5, c: 3, d: 4}
//對你沒看錯defineProperty有這個功能,不知能夠定義新的屬性還能夠修改,這麼逆天難用的功能爲何還要造出來?說這個有什麼用?別急往下看segmentfault
descriptor (必須有 官方說的我理解不了,我理解的是 屬性描述
一、簡單點就是 設置屬性的值value,
二、是否可操做屬性值 writable,
三、是否可修改配置configurable若是值爲false descriptor內的屬性都不可操做)
四、是否可枚舉enumerablespa
先作了介紹咱們下邊來證實下雙向綁定
//栗子仍是這個栗子 let obj = { a: 1 } Object.defineProperty(obj, 'b', { value: 2, writable: false//不可修改 }) obj.b = 3 console.log(obj) //{a: 1, b: 2} 還真是不能夠 //難道是姿式不對? Object.defineProperty(obj, 'b', { value: 3 }) console.log(obj)//{a: 1, b: 2} 同樣的效果 和姿式無關。
//configurable 這個比較厲害 控制descriptor內屬性都不可改變不知道是否是真的code
//仍是這個栗子htm
let obj = { a: 1 } Object.defineProperty(obj, 'b', { value: 2, //writable: false//不可修改 configurable: false }) obj.b = 5 console.log(obj)//[1,2]
對否可枚舉對象
let obj = { a: 1 } Object.defineProperty(obj, 'b', { value: 2, //writable: false//不可修改 //configurable: false enumerable: false }) //obj.b = 5 console.log(Object.keys(obj))//["a"]
接了下來講到重點: set和get這也是vue3.0前observe的實現原理ip
let obj = { a: 1 } let newValue = 45 Object.defineProperty(obj, 'b', { get(value) { console.log('獲取') return value }, set(newValue) { console.log('設置') value = newValue } }) obj.b = 6 //設置 obj.b //獲取
知道用法了咱們來實踐一下rem
//html <div></div> <input type="text"> //js //相似 vue的data let obj = {} /* *obj 要劫持的對象 *name 要劫持對象的屬性 *callback 劫持之後的操做 */ function watch(obj, name, callback) { let value = obj.name Object.defineProperty(obj, name, { set(msg) { // 觸發setter給obj賦值 value = msg //執行劫持後的操做 callback(value) }, get() { //返回獲取屬性值 return value } }) } // function doSomething(value) { document.querySelector('div').innerHTML = value document.querySelector('input').value = value } //監聽input變化 //能夠參考全兼容版:https://segmentfault.com/a/1190000017524278 document.querySelector('input').addEventListener('input', (e) => { obj['msg'] = e.target.value }) watch(obj, 'msg', doSomething)
效果:
一、input輸入改變div內容
二、改變obj name屬性
三、獲取改變後的obj屬性name
簡單的用defineProperty實現了雙向綁定
歡迎吐槽!您的點贊是我繼續的動力!謝謝