每天寫一點(單向數據流、觀察者模式)

前言

最近每天學的都是些查缺補漏的知識,深度一般廣度到不少,因此用這樣的方式做個每日總結感覺還不錯,今天主要寫三個東西,一個是偶然看到的易混點,一個是發佈訂閱模式與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等,呼~加上算法題,有夠折騰的了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章