前端知識梳理

Webpack

ESLint

CI(Continuous integration)

瀏覽器原理

  • async 和 defer
    • 一張圖:

Web Component

React

生命週期

  • 一張圖:
  • setState 爲何是異步的?
    • 批量更新事務
      • batchingStrategy.isBatchingUpdates 和 batchingStrategy.batchedUpdates()
      • react是經過合成事件實現了對於事件的綁定,當進入事件處理流程後,該事務的isBatchingUpdates爲true,若是在事件中調用setState方法,也會進入dirtyComponent流程。
      • 若是咱們在瀏覽器的 click 句柄(handler)中,Child 和 Parent 都調用了 setState,則咱們不但願從新渲染 Child 兩次,而是傾向於將它們標記爲髒,而後在瀏覽器事件結束的時候從新渲染它們。
    • 保證內部一致性
    • 使併發更新變得可行:React 能夠根據 setState() 來自的不一樣的位置:事件句柄,網絡響應,動畫等,來爲它們分配不一樣的優先級。
  • 鉤子函數(函數組件不能使用這些方法,由於這須要繼承react Component這個類)
    • constructor(props, context)
    • getDefaultProps()
      • 對於每一個組件實例來說,這個方法只會調用一次,該組件類的全部後續應用,getDefaultPops 將不會再被調用,其返回的對象能夠用於設置默認的 props值。
    • getInitialState()
      • 對於組件的每一個實例來講,這個方法的調用有且只有一次,用來初始化每一個實例的 state,在這個方法裏,能夠訪問組件的 props。
      • getInitialState 和 getDefaultPops 的調用是有區別的,getDefaultPops 是對於組件類來講只調用一次,後續該類的使用都不會被調用,至關於 Object.prototype.XXX。而 getInitialState 是對於每一個組件實例來說都會調用,而且只調一次,至關於 this.XXX
    • componentWillMount()
      • 在組件掛載到DOM前調用,且只會被調用一次,在這邊調用this.setState不會引發組件從新渲染,也能夠把寫在這邊的內容提早到constructor()中,因此項目中不多用。
    • render()
      • 根據組件的props和state(無二者的重傳遞和重賦值,論值是否有變化,均可以引發組件從新render) ,return 一個React元素(描述組件,即UI),不負責組件實際渲染工做,以後由React自身根據此元素去渲染出頁面DOM。render是純函數(Pure function:函數的返回結果只依賴於它的參數;函數執行過程裏面沒有反作用),不能在裏面執行this.setState,會有改變組件狀態的反作用。
      • setState引發的state更新 或 父組件從新render引發的props更新,更新後的state和props相對以前不管是否有變化,都將引發子組件的從新render。可經過shouldComponentUpdate方法優化。
    • componentDidMount()
      • 組件掛載到DOM後調用,且只會被調用一次,這裏通常是發起異步請求,由於在componentWillMount裏發起AJAX,無論多快獲得結果也趕不上首次render。
      • 該方法被調用時,已經渲染出真實的 DOM,能夠再該方法中經過 this.getDOMNode() 訪問到真實的 DOM(推薦使用 ReactDOM.findDOMNode())。
    • componentWillReceiveProps(nextProps)
      • 在此函數中調用 this.setState() 將不會引發第二次渲染。因此能夠把外部 props 轉換成本身的state,達到優化渲染的效果。
    • shouldComponentUpdate(nextProps, nextState)
      • true:從新加載組件
      • false:不更新組件
    • componentWillUpdate(nextProps, nextState)
      • 此方法在調用render方法前執行,在這邊可執行一些組件更新發生前的工做,通常較少用。
    • re- render() 從新調用
    • componentDidUpdate(prevProps, prevState)
      • 此方法在組件更新後被調用,能夠操做組件更新的DOM,prevProps和prevState這兩個參數指的是組件更新前的props和state
    • componentWillUnmount()
      • 此方法在組件被卸載前調用,能夠在這裏執行一些清理工做,好比清楚組件中使用的定時器,清楚componentDidMount中手動建立的DOM元素等,以免引發內存泄漏。
  • 16版本新增生命週期
    • static getDerivedStateFromProps(props, state)
      • 在組件建立時和更新時的render方法以前調用,它應該返回一個對象來更新狀態,或者返回null來不更新任何內容。強制開發者在render以前只作無反作用的操做,並且能作的操做侷限在根據props和state決定新的state,而已。
    • getSnapshotBeforeUpdate()
      • 被調用於render以後,能夠讀取但沒法使用DOM的時候。它使您的組件能夠在可能更改以前從DOM捕獲一些信息(例如滾動位置)。今生命週期返回的任何值都將做爲參數傳遞給componentDidUpdate(prevProps, prevState, snapshot)

Context

  • 解決嵌套組件自頂向下多層傳遞 props 和 state 的問題,this.context.XXX 能夠跨級傳遞數據。
  • 生產者消費者模式
    • 父組件是生產者,父組件必須用靜態屬性 childContextTypes 聲明提供給子組件的 Context 內容,並實現一個實例getChildContext方法,返回一個表明Context的純對象 (plain object)
    • 子組件是消費者,子組件必須用靜態屬性 contextTypes 申請要消費的 Context 內容,以後才能經過 this.context.XXX 來訪問父組件提供的 Context 內容。
  • 無狀態子組件
    • 使用:ChildComponent = (props, context) => {console.log(context.propsA)};
    • 聲明:ChildComponent.contextProps = { propA: PropTypes.string };
  • React.createContext() 會建立一個 Context 對象(例如 TestContext)
    • <Provider /><TestContext.Provider value={{propsA: 'xxxxx'}} /> 的value至關於的 getChildContext()
    • <Consumer /><TestContext.Consumer>{context => (<h1>{context.propsA}</h1>)}</TestContext.Consumer> 的children必須是一個函數,經過函數的參數獲取<Provider />提供的Context。
  • context 從哪來
    • this.context
    • constructor(props, context)
    • componentWillReceiveProps(nextProps, nextContext)
    • shouldComponentUpdate(nextProps, nextState, nextContext)
    • componetWillUpdate(nextProps, nextState, nextContext)
    • 無狀態函數式組件 ChildComponent = (props, context) => {console.log(context.propsA)};
  • 爲何要用父聲明子申請的設計
    • 父子組件是一對多的線性依賴。隨意的使用Context其實會破壞這種依賴關係,致使組件之間一些沒必要要的額外依賴,下降組件的複用性,進而可能會影響到App的可維護性。經過childContextTypes和contextTypes這兩個靜態屬性的約束,能夠在必定程度保障,只有組件自身,或者是與組件相關的其餘子組件才能夠爲所欲爲的訪問Context的屬性,不管是數據仍是函數。

JSX

React-Router

Redux

數據流

  • 一張圖:
  • Store > subscribe > Component > trigger >Action > dispatch > Reducer > put > Store

Reducer

  • 一個純函數,執行一個action而且返回一個新的狀態。
  • 入參是state 和 action
    • state是當前保存在store中的數據,初始時無值須要入參處指定初始值。
    • action至關於一個容器,有兩個 key
      • type - 一個簡單的字符串常量,例如ADD, UPDATE, DELETE等。
      • payload - 用於更新state的數據。
  • 代碼設計上不該該在reducer裏用 if-else/switch 來取針對不一樣的 action.type作業務處理,service code 不該該寫在這一層,應該用 myActionsaction.type 解耦。dva就是作了這件事,把 action處理單獨抽出來
  • 多個 reducer 的場景:let store = redux.createStore(redux.combineReducers({reducer1, reducer2}));
  • Action觸發流:
    • 抽離的 action 方法是接收 payload,組裝並返回一個 action 容器,例如 function action1(data1, data2) {return {type: 'ACTION_1', payload: {data1, data2}}};
    • 用 store.dispatch()去分發這個 action:如 store.dispatch(action1('data_1', 'data_2'));
    • reducer接收到相應的 action 開始處理:如 reducer1(state, action){ if(action.type === 'ACTION_1'){return {...state, ...action.payload}};
  • Immutability(不可變性)
    • 若是代碼只處理原始數據類型(numbers, strings, booleans),那麼你不用擔憂。可是,若是在處理Arrays和Objects時,則須要當心執行可變操做。不可變操做實現有 immutable.js/Object.assign()/{...Obj}
    • immutable.js
  • React 結合
    • react-redux
      • 用 Provider 包起來 ReactDOM.render(<Provider store={store}> <h1>xxx</h1></Provider>, document.getElementById('root'));
  • 異步數據處理
    • Redux自己只能處理同步的Action,但能夠經過中間件來攔截處理其它類型的action,好比 Thunk 函數,再用回調觸發普通Action,從而實現異步處理,在這點上全部Redux的異步方案都是相似的。
    • 概念
      • 模板代碼
      • 樂觀更新
      • 錯誤處理
      • 競態
    • 模塊
      • redux-thunk
      • redux-promise
      • redux-loop
      • redux-saga
      • redux-observable
      • redux-action-tools

Diff

Vue

生命週期

  • 一張圖:
  • 鉤子函數(Vue的全部生命週期函數都是自動綁定到this的上下文上,因此箭頭函數會報錯)
    • beforeCreatehtml

    • createdvue

    • el 和 template 過程參與node

      • 實例沒有指定 el 屬性時就不會觸發下面的 beforeMount 和 mounted,能夠用$mount 方法手動掛載 el,生命週期方法會按序觸發。
      • render函數 > template屬性 > 外部html, vue 的編譯過程就是把tempalte編譯成render函數的過程。
    • beforeMountreact

    • mountednginx

    • beforeUpdate編程

      • 這裏的數據只有和模版中的數據綁定了纔會發生更新,纔會調用 berforeUpdate 和 updated 這兩個鉤子。
    • updatedredux

    • beforeDestroy數組

      • 在 beforeDestroy 生命鉤子調用以前,全部實例均可以用,可是當調用後,Vue 實例的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
    • destroyedpromise

    • 其餘鉤子瀏覽器

      • activated:當組件激活的時候調用
      • deactivated:當組件停用的時候調用
      • errorCaptured:這個生命鉤子能夠看官網,2.5.0以後纔有的。當捕獲一個來自子孫組件的錯誤時被調用。

自帶屬性方法

  • data = $data
    • 在定義一個組件時,data 必須聲明爲一個返回初始數據對象的無反作用的函數,由於可能會使用此函數建立多個實例。若是 data 是一個普通對象,則全部建立出來的實例將共享引用同一個數據對象!
    • data: (vm) => ({x: vm.myProp});

指令

  • v-text = textContent
  • v-html = innerHtml
  • v-bind:href = :href
    • 做用:當表達式的值改變時,將其產生的連帶影響,響應式地做用於 DOM
    • 語法:v-bind:href="url"
    • 簡寫::href="url"
    • 說明:綁定的數據從 data 或 props中獲取
  • v-on:click = @click
    • 做用:綁定事件
    • 語法:v-on:click="say" or v-on:click="say('參數', $event)"
    • 簡寫:@click="say"
    • 說明:綁定的事件從methods中獲取
    • 事件修飾符 *v-on:click.stop="say" 阻止冒泡,調用 event.stopPropagation()
      • v-on:click.prevent 阻止默認事件,調用 event.preventDefault()
      • v-on:click.capture="say" 添加事件偵聽器時使用事件捕獲模式
      • v-on:click.self="say" 只當事件在該元素自己(好比不是子元素)觸發時觸發回調
      • v-on:click.once="say" 事件只觸發一次
      • 順序很重要v-on:click.prevent.self 會阻止全部的點擊,而 v-on:click.self.prevent 只會阻止對元素自身的點擊。
  • v-model
    • 做用:在表單元素上建立雙向數據綁定
    • 說明:監聽用戶的輸入事件以更新數據
    • demo: <input v-model="message" placeholder="edit me"><p>Message is: {{ message }}</p>
  • v-for
    • item 爲值,key 爲鍵,index 爲索引
    • demo: <p v-for="(item, key, index) in obj" :key="item.key">{{item}} -- {{key}}</p>
    • 性能:使用 key,VUE會基於 key 的變化從新排列元素順序,而且會移除 key 不存在的元素。
  • 樣式處理 v-bind
    • :class="[{active: true}, 'warning', errorClass]"
    • :style="[{fontSize: fs + 'px'}, baseStyle, overridingStyles]"
  • v-if: 根據表達式的值的真假條件,銷燬或重建元素
  • v-show: 根據表達式之真假值,切換元素的 display CSS 屬性
  • 性能和體驗
    • v-cloak: 這個指令保持在元素上直到關聯實例結束編譯。
      • 防止未編譯的 Mustache 模板數據出如今頁面上。
      • CSS 樣式 [v-cloak] { display: none } 能夠在實例 ready 前隱藏未編譯的 Mustache 標籤。
    • v-pre: 跳過這個元素和它的子元素的編譯過程。能夠用來顯示原始 Mustache 標籤,跳過大量沒有指令的節點會加快編譯。
    • v-once: 只渲染元素和組件一次。隨後的從新渲染,元素/組件及其全部的子節點將被視爲靜態內容並跳過。這能夠用於優化更新性能。
  • 自定義指令
    • 全局註冊
      • 註冊方法:Vue.directive( directiveName, [definition] )
      • demo:
      <div id="app" class="demo">
          <!-- 全局註冊 -->
          <input type="text" v-focus>
      </div>
      <script>
          Vue.directive("focus", {
              inserted: function(el){
                  el.focus();
              }
          })
          new Vue({
              el: "#app"
          })
      </script>
      複製代碼
    • 局部註冊
      • 註冊方法:在Vue實例中添加 directives 對象
      • demo:
      <div id="app" class="demo">
          <!-- 局部註冊 -->
          <input type="text" v-focus2>
      </div>
      <script>
          new Vue({
              el: "#app",
              directives: {
                  focus2: {
                      inserted: function(el){
                          el.focus();
                      }
                  }
              }
          })
      </script>
      複製代碼
    • 自定義指令的鉤子函數
      • bind(el, binding, vnode):只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。
      • inserted(el, binding, vnode):被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)。
      • update(el, binding, vnode, oldVnode):所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前。指令的值可能發生了改變,也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新。
      • componentUpdated(el, binding, vnode, oldVnode):指令所在組件的 VNode 及其子 VNode 所有更新後調用。
      • unbind(el, binding, vnode):只調用一次,指令與元素解綁時調用。

Vue-Router

VueX

Node

EventLoop

  • 一張圖:
  • Timer(setTimeout/setInterval) --tick-- I/O --tick-- Check(setImmediate)
  • macrotasks: setTimeout setInterval setImmediate I/O UI渲染
  • microtasks: Promise process.nextTick Object.observe MutationObserver
  • 一個有趣的例子:process.nextTick是註冊在當前的tick階段進行拼接,繼續執行,從而致使了死循環
process.nextTick(function tick () {
  process.nextTick(tick) 
});
複製代碼

函數式編程

柯里化

function realSum(...args) {
    return args.reduce((prev, next) => prev + next, 0);
}
function sum(...args1) {
    let value = realSum(...args1);
    function fn(...args2) {
        value += realSum(...args2)
        return fn
    };
    fn.valueOf = () => value;
    return fn;
}

sum(1,2)(3)(4)(2,3).valueOf(); // 15
複製代碼

尋找對稱數

function findSymmetricNum(min, max) {
    let num = min;
    let temp = '';
    const result = [];
    for(let i=0; i< max-min+1;i++) {
        temp = num + '';
        // 字符串反轉後是否與以前相等
        if(temp.split('').reverse().join('') === temp) {
            result.push(num);
        }
        num ++;
    }
    return result;
};

複製代碼

異步鏈式調用

複製代碼

Sass

Less

HTTP

原理

HTTP2

長連接複用

數據 chunk 方式通訊

CDN

  • 查找鏈路
    • 一張圖:
    • 客戶端 -> ( * CNAME:把自有域名換成 cdn 域名) -> DNS查詢 -> 全局負載均衡系統 -> (透傳客戶端 IP 和目標資源 URL) -> 區域負載均衡系統 ->(根據客戶端 IP 和目標資源 URL,獲取距離客戶端最近且有相應資源的cdn 緩存服務器的地址) -> 全局負載均衡系統 -> (cdn 緩存服務器地址)-> 客戶端 -> (請求緩存服務器上的文件)
  • 回源
    • 當 cdn 緩存服務器中沒有符合客戶端要求的資源的時候,緩存服務器會請求上一級緩存服務器,以此類推,直到獲取到。最後若是仍是沒有,就會回到咱們本身的服務器去獲取資源。沒有資源,資源過時,訪問的資源是不緩存資源等都會致使回源。
  • 更新數據
    • 主動(PUSH)
    • 被動(PULL)

DNS

  • 一張圖

  • 查找方式

    • 遞歸查詢:遞歸查詢是一種DNS 服務器的查詢模式,在該模式下DNS 服務器接收到客戶機請求,必須使用一個準確的查詢結果回覆客戶機。若是DNS 服務器本地沒有存儲查詢DNS 信息,那麼該服務器會詢問其餘服務器,並將返回的查詢結果提交給客戶機。
    • 迭代查詢:DNS 服務器會向客戶機提供其餘可以解析查詢請求的DNS 服務器地址,當客戶機發送查詢請求時,DNS 服務器並不直接回複查詢結果,而是返回客戶機另外一臺DNS 服務器地址,客戶機再向這臺DNS 服務器提交請求,依次循環直到返回查詢的結果爲止。
  • 多域名查詢優化

TypeScript

Node

多進程開發

nginx 原理

PM2

反模式

相關文章
相關標籤/搜索