前言
最近每天學的都是些查缺補漏的知識,深度一般廣度到不少,因此用這樣的方式做個每日總結感覺還不錯,今天主要寫三個東西,一個是偶然看到的易混點,一個是發佈訂閱模式與Vue的結合問題,還有就是一次nice的面試收穫。
怎麼理解React沒有實現數據雙向綁定
首先React不是一個MVVM框架,他只是一個View層的庫,而View層的數據渲染,即簡單的props和state,並不需要雙向綁定也能滿足基本需求,所以它並不是不能做,只是沒必要做。
那React怎麼實現的狀態改變之後,視圖也更新了呢?比較簡單的理解就是通過重新渲染,React是不會主動監聽視圖的變化的,每次渲染組件就是一個全新的狀態,不追蹤原來的變化,也就談不上數據綁定的實現。對於Input組件這種需要依賴數據變化的場景,則使用類似操作DOM的場景,利用合成事件手動通知狀態的改變。
如果還不理解的話,這篇文章個人感覺還不錯。
綜上,在React,實現數據的雙向綁定是通過受控組件完成的,這也是React官方推薦的方式。
觀察者模式
正在看這個的時候撇了一眼手機,接到了阿里爸爸的電話,,,
這差不多是前端領域使用最多的設計模式了,可以拿出來說的也有很多,典型的就有Vue的響應式原理,全局事件總線等。
關於Vue的響應式原理,官網有詳細的講解,這裏簡單的說一下,首先利用Proxy或Object.defineProperty生成的Observer既充當了監聽器的作用,又充當發佈者的角色,在數據屬性變化後來通知訂閱者;同時Compile解析模板中的指令,收集指令依賴的方法和數據,等待數據變化後的渲染;最後watcher連接兩者,使得訂閱依賴的數據變化轉化爲視圖的變化。
插句話,Proxy優化了Object.defineProperty對於新增屬性不被攔截、不需要遍歷對象屬性進行修改等問題,在immer這樣的庫中也得到了廣泛使用。
準確的說,Vue實現了觀察者模式,微微區別於發佈訂閱模式的一點,所有的操作都需要經過事件中心去完成,這裏寫一個簡單的Event Bus
class Event {
constructor() {
this.handlers = {};
}
on(event, cb) {
if (!this.handlers[event]) {
this.handlers[event] = [];
}
this.handlers[event].push(cb);
}
emit(event, ...args) {
if (this.handlers[event]) {
this.handlers[event].forEach(callback => {
callback(...args);
});
}
}
off(event, cb) {
const callbacks = this.handlers[event];
const index = callbacks.indexOf(cb);
if (index !== -1) {
callbacks.splice(index, 1);
}
}
once(event, cb) {
const wrapper = (...args) => {
cb.apply(...args);
this.off(event, wrapper);
};
this.on(event, wrapper);
}
}
一次nice的interview
點贊alipay的大佬,整個過程都有幫助解答,收穫很多,感覺部分東西要抽一天來消化一下,這裏大致提一下,各種CSS方案解決作用域問題的解決原理,IFC之類的問題,圖層之類的問題,polyfill的實現,hidden_class等,呼~加上算法題,有夠折騰的了。