動態數據綁定的三個難點:前端
對象深度問題vue
設置新對象是否可以繼續響應getter 和 settergit
考慮傳遞迴調函數github
在實踐中使用遞歸思想設計模式
瞭解設計模式中的「發佈-訂閱模式」微信
若是傳入參數對象是一個「比較深」的對象(也就是其屬性值也多是對象),那該怎麼辦呢?舉個例子。app
// 一個「比較深」的對象:某些屬性的值也是一個對象 let obj = { a: 1, b: 2, c: { d: 3, e: 4 } }
若是設置新的值是一個對象的話,新設置的對象的屬性是否能能繼續響應 getter 和 setter。舉個例子。函數
// 一個「比較深」的對象:某些屬性的值也是一個對象 let app1 = new Observer({ name: 'youngwind', age: 25 }); app1.data.name = { lastName: 'liang', firstName: 'shaofeng' }; app1.data.name.lastName; // 這裏還須要輸出 '你訪問了 lastName ' app1.data.name.firstName = 'lalala'; // 這裏還須要輸出 '你設置了firstName, 新的值爲 lalala'
考慮傳遞迴調函數。在實際應用中,當特定數據發生改變的時候,咱們是但願作一些特定的事情的,而不是每一次都只能打印出一些信息。因此,咱們須要支持傳入回調函數的功能。舉個例子。學習
let app1 = new Observer({ name: 'youngwind', age: 25 }); // 你須要實現 $watch 這個 API app1.$watch('age', function(age) { console.log(`個人年紀變了,如今已是:${age}歲了`) }); app1.data.age = 100; // 輸出:'個人年紀變了,如今已是100歲了'
對象深度問題解決方法this
walk(obj){ let val; for(let key in obj){ // 這裏爲何要用hasOwnProperty進行過濾呢? // 由於for...in 循環會把對象原型鏈上的全部可枚舉屬性都循環出來 // 而咱們想要的僅僅是這個對象自己擁有的屬性,因此要這麼作。 if(obj.hasOwnProperty(key)){ val = obj[key]; //第一大難題:初始化深對象解決問題 這裏進行判斷,若是尚未遍歷到最底層,繼續new Observer if(typeof val === 'object'){ new Observer(data) } this.convert(key,val); } } }
使用遞歸的方式 . 利用 typeof 來檢查 val 是不是 object 對象 ,若是是則進行遞歸,檢查其子屬性...遞歸..
設置新對象是否可以繼續響應getter 和 setter
set: function (valnew) { self.watch[key](valnew) // 回調監聽 取代下面那條語句 //console.log(`你設置了 ${key}, 新的值爲${valnew}`); if (typeof newVal === 'object') { new Observer(valnew); } if (valnew === val) return; val = valnew }
同第一個難點,在 setter 處,判斷改變後的屬性值是不是對象 若是是對象 則再從新new 一個Observer出來
考慮傳遞迴調函數
$watch(key,callback){ this.watch[key] = callback; }
仿照 JavaScript 設計模式 發佈-訂閱模式 來寫一個進行 setter 時,觸發函數
更多設計模式相關的資料強烈推薦曾探所著《JavaScript設計模式與開發實踐》
上篇文章Vue 動態數據綁定(一)
更多內容能夠訂閱本人微信公衆號,一塊兒開啓前端小白進階的世界!