1.Object.defineProperty(obj,key,desc);javascript
用法:1.給對象新增屬性和特性vue
2.修改對象屬性值和特性java
desc(屬性特性):數組
1.enumerable:boolean 可枚舉函數
2.writable :boolean 可寫雙向綁定
3.value:any 賦值server
4.get 取值對象
5.set 改值blog
2.思路:ip
對象的賦值和改值實際上是經過Object.defineProperty的get和set特性來實現的,通常默認模式。
經過改寫屬性的get和set的特性,來實現對一個對象的監聽。
3.舉例:
var obj = {age:23}; console.log(obj.age); //23 Object.defineProperty(obj,'age',{ get(){ return 24; } }); console.log(obj.age); //24 obj.age = 25; console.log(obj.age); //24
原理:對象屬性和賦值取值都會觸發自身的get和set特性。
4.實現:
/*js 監聽器*/ var transi = ""; function observe(obj,key){ if(obj[key] && (typeof obj[key] == 'object')){ Object.keys(obj[key]).forEach((v,index)=>{ observe(obj[key],v,obj[key][v]); }); } else { Object.defineProperty(obj,key,{ set(newV){ transi = newV; console.log('值改變'); }, get(){ console.log('新值爲' + transi); return transi; } }) } } var obj = {name : 'wang',age:{max:12,good:{at:30}}}; observe(window,'obj'); obj.age.good.at = 44; console.log(obj.age.good.at);
5.延伸:
vue的雙向綁定機制:當改變一個值時,在這個值的set特性中觸發其餘值的改變,實現數據實時更新的機制。
6.核心:
1.observer觀察者: 觀察一個對象,當某一屬性改變時,觸發set特性,由set觸發與之關聯的屬性,哪些與之關聯,怎麼創建起關係?須要一個訂閱者,即爲一個數組,存放一些關聯的對象。
2.watcher訂閱者: 訂閱者須要本身的更新機制,在set中被觸發時須要及時更新本身的數據,再渲染到頁面上,須要complier來解析頁面,實現view層改變。
3.complier解析: 經過js獲取指令模板,正則匹配換值,將操做封裝放進set函數中實現view層自動更新。