每週分享第 2 期

更新:謝謝你們的支持,最近折騰了一個博客官網出來,方便你們系統閱讀,後續會有更多內容和更多優化,猛戳這裏查看javascript

------ 如下是正文 ------css

這裏分享過去一週高級前端進階羣裏的學習彙總,天天會在羣裏給你們發一些資料一塊兒學習,晚上會上傳個人筆記,內容之前端基礎、源碼分析、面試題解爲主,若是你上班沒時間看,那週末能夠好好學習了,彎道超車重在堅持。html

本週學習彙總

11月9號

  • HTML5 History 模式前端

    • vue-router 默認使用hash 模式來模擬一個完整的 URL,當 URL 改變時,頁面不會從新加載。vue

    • 用路由的 history 模式替換hash模式,利用 history.pushState API 來完成 URL 跳轉而無須從新加載頁面。java

      const router = new VueRouter({
        mode: 'history',
        routes: [...]
      })
      複製代碼
    • 後臺須要對路由進行配置react

  • 理解 Javascript 執行上下文和執行棧(優)webpack

    • 執行上下文總共有三種類型:全局執行上下文函數執行上下文(只有在函數被調用的時候纔會被建立)、Eval 函數執行上下文git

    • LIFO原則,引擎首次讀取腳本時,會建立一個全局執行上下文並將其推入當前的執行棧。每當發生一個函數調用,引擎都會爲該函數建立一個新的執行上下文並將其推到當前執行棧的頂端。函數運行完成後,其對應的執行上下文將會從執行棧中彈出,上下文控制權將移到當前執行棧的下一個執行上下文。github

    • 執行上下文分兩個階段建立:1)建立階段; 2)執行階段

    • 建立階段發生三件事:1)肯定 this 的值,也被稱爲 This Binding2)LexicalEnvironment(詞法環境) 組件被建立。3)VariableEnvironment(變量環境) 組件被建立。

    • 環境記錄 還包含了一個 arguments 對象,該對象包含了索引和傳遞給函數的參數之間的映射以及傳遞給函數的參數的長度(數量)

      function foo(a, b) {  
        var c = a + b;  
      }  
      foo(2, 3);
      
      // arguments 對象 
      Arguments: {0: 2, 1: 3, length: 2},
      複製代碼
    • 在建立階段,函數聲明存儲在環境中,而變量會被設置爲 undefined(在 var 的狀況下)或保持未初始化(在 letconst 的狀況下)。因此這就是爲何能夠在聲明以前訪問 var 定義的變量(儘管是 undefined ),但若是在聲明以前訪問 letconst 定義的變量就會提示引用錯誤的緣由。這就是所謂的變量提高。

    • 若是 Javascript 引擎在源代碼中聲明的實際位置找不到 let 變量的值,那麼將爲其分配 undefined 值。

  • JavaScript萬物產生順序(優)

    • 對於 Object 來講,它是一個 Function的實例,由於 Object instanceof Function // true;對於 Function 來講,它是 Object 的實例,由於 Function instanceof Object // true,因此究竟是先有 Object 仍是先有 Function呢?

    • 一種理解:Object基於 null 爲模板(__proto__),因此Object.prototype.__proto__ === null

    • new Object 建立一個對象,基於Object.prototype爲模板,因此new Object({}).__proto__ === Object.prototype

      // Object
      new Object().__proto__ === Object.prototype;
      Object.__proto__ === Function.prototype;
      Object.prototype.__proto__ === nulll;
      
      // Function
      Function.prototype === Function.__proto__;
      Function.prototype.__proto__ === Object.prototype;
      
      // Foo
      new Foo().__proto__ === Foo.prototype;
      Foo.prototype.__proto__ === Object.prototype;
      Foo.__proto__ === Function.prototype
      複製代碼

      image

11月8號

  • ES6 系列之 Babel 是如何編譯 Class 的(下)(優)

    • 寄生組合式繼承優勢在於只調用一次 Parent 構造函數,避免了在 Parent.prototype 上面建立沒必要要的、多餘的屬性,同時原型鏈還能保持不變。

    • ES6的super 關鍵字表示父類的構造函數,至關於 ES5 的 Parent.call(this)。因此子類只有調用 super 以後,纔可使用 this 關鍵字

    • 子類的 __proto__ 屬性,表示構造函數的繼承,老是指向父類。

    • 子類 prototype 屬性的__proto__屬性,表示方法的繼承,老是指向父類的 prototype 屬性。

    • 相比寄生組合式繼承,ES6 的 class 多了一個 Object.setPrototypeOf(Child, Parent) 的步驟。

    • 語法糖其實用的就是Object.create(),第一個參數是新建立的對象,第二個參數表示要添加到新建立對象的屬性,注意這裏是給新建立的對象即返回值添加屬性,而不是在新建立對象的原型對象上添加。

    • 首先執行 _inherits(Child, Parent),創建 Child 和 Parent 的原型鏈關係,即Object.setPrototypeOf(Child.prototype, Parent.prototype)Object.setPrototypeOf(Child, Parent)。而後調用 Parent.call(this, name),根據 Parent 構造函數的返回值類型肯定子類構造函數 this 的初始值 _this。最終,根據子類構造函數,修改 _this 的值,而後返回該值。

  • 構建Promise隊列實現異步函數順序執行

    • 場景:有a、b、c三個異步任務,要求必須先執行a,再執行b,最後執行c,且下一次任務必需要拿到上一次任務執行的結果,才能作操做。

    • 解決方法一:使用then鏈式操做

      //鏈式調用
      a()
        .then(function (data) {
          return b(data)
        })
        .then(function (data) {
          return c(data)
        })
        .then(function (data) {
          console.log(data) // abc
        })
      複製代碼
    • 解決方法二:構建隊列

      // 構建隊列
      function queue(arr) {
        let sequence = Promise.resolve()
        arr.forEach(function (item) {
          sequence = sequence.then(item)
        })
        return sequence
      }
      
      // 執行隊列
      queue([a, b, c])
        .then(data => {
          console.log(data) // abc
        })
      複製代碼
    • 解決方法三:使用async、await構建隊列

      async function queue(arr) {
          let res = null
          for (let promise of arr) {
              res = await promise(res)
          }
          return await res
      }
      
      queue([a, b, c])
          .then(data => {
          	console.log(data) // abc
      	})
      複製代碼
  • URL中的#

    • javascript 能夠經過 window.location.hash來讀取或改變 #

    • location.href += '#caper'; 瀏覽器滾動到新的位置,但頁面不會刷新,改變了瀏覽器記錄,能夠經過瀏覽器上一頁按鈕回到原始的位置。

    • HTML 5新增onhashchange 事件,對於不支持onhashchange的瀏覽器,能夠用setInterval監控location.hash的變化。

      // 使用方法有三種
      window.onhashchange = func;
      
      <body onhashchange="func();"> window.addEventListener("hashchange", func, false); 複製代碼

11月7號

  • React事件系統和源碼淺析(優)

    • 一、React爲了性能複用,採用了事件代理,池,批量更新,跨瀏覽器和跨平臺兼容等思想,將事件監聽掛載在document上構造合成事件,在內部模擬了一套捕獲冒泡並觸發回調函數的機制
    • 二、執行順序:document原生事件 --> 合成事件(冒泡 innerClick --> outerClick)--> window
    • 三、若是是由React引起的事件處理(好比經過onClick引起的事件處理),調用setState會異步更新state。除此以外的setState調用會同步執行state,包括經過addEventListener直接添加的事件處理函數,還有經過promise/setTimeout/setInterval產生的異步調用。
    • 四、React合成的SyntheticEvent採用了的思想,從而達到節約內存,避免頻繁的建立和銷燬事件對象的目的。
    • 五、React源碼中隨處可見batch作批量更新,基本上凡是能夠批量處理的事情(最廣泛的setState)React都會將中間過程保存起來,留到最後面才flush掉。
    • 六、異步渲染的狀況下假如我點了兩次按鈕,那麼第二次按鈕響應的時候,可能第一次按鈕的handlerA中調用的setState還未最終被commit到DOM樹上,這時須要把第一次按鈕的結果先給flush掉並commit到DOM樹,纔可以保持一致性。
  • Vue 生命週期梳理

    • 一、beforeCreate中拿不到任何數據,在vue實例化以後
    • 二、created中已經能夠拿到data中的數據了,可是dom尚未掛載,適合ajax請求和頁面初始化
    • 三、beforeMount 頁面掛載以前
    • 四、mounted 頁面掛載成功,vue實例對象中有template參數選項,則將其做爲模板編譯成render函數,編譯優先級render函數選項 > template選項
    • 五、beforeUpdate 頁面更新以前
    • 六、updated 頁面已更新成功
    • 七、destroyed 實例化銷燬,用於解除綁定
    • 八、處理 HTML 標記並構建 DOM 樹,處理 CSS 標記並構建 CSSOM 樹,將 DOM 與 CSSOM 合併成一個渲染樹。根據渲染樹來佈局,以計算每一個節點的幾何信息,將各個節點繪製到屏幕上。
  • JavaScript 複雜判斷的更優雅寫法(優)

    • 一、一個對象的鍵只能是字符串或者Symbols,但一個Map的鍵能夠是任意值。、
    • 二、經過size屬性很容易地獲得一個Map的鍵值對個數,而對象的鍵值對個數只能手動確認。
    • 三、actions是Map對象時,[...actions]能夠轉換成數組
    • 四、在Map中能夠用正則類型做爲key,這樣就有了無限可能

11月6號

  • ES6 系列之 Babel 是如何編譯 Class 的(上)

    • 一、ES5 的構造函數對應 ES6 的constructor 方法。

    • 二、ES6定義的全部方法,都是不可枚舉的。

    • 三、在方法前加上 static 關鍵字不會被實例繼承,是直接經過類來調用,這個是"靜態方法"。

    • 四、類和普通構造函數的一個主要區別是類必須使用 new 調用,不然會報錯。

    • 五、使用 get 和 set 關鍵字攔截屬性默認行爲

    • 六、Babel 轉換經過_classCallCheck檢查類是不是經過 new 的方式調用

    • 七、靜態屬性static bar = 'bar'轉換成Person.bar = 'bar'

    • 八、Babel 生成了一個 _createClass 輔助函數,該函數傳入三個參數,第一個是構造函數,在這個例子中也就是 Person,第二個是要添加到原型上的函數數組,第三個是要添加到構造函數自己的函數數組,也就是全部添加 static 關鍵字的函數。該函數的做用就是將函數數組中的方法添加到構造函數或者構造函數的原型中,最後返回這個構造函數。

  • ES6的Symbol居然那麼強大,面試中的加分點

    • 一、symbol for 全局共享Symbol
    • 二、symbol keyFor 獲取全局共享Symbol的key
    • 三、Object.getOwnPropertySymbols獲取Symbol
    • 四、Symbol.hasInstance 內部方法,判斷某對象是否爲某構造器的實例
    • 五、Symbol.toPrimitive內部方法,轉換爲原始值,加法運算會觸發三種類型轉換:將值轉換爲原始值,轉換爲數字,轉換爲字符串
  • 【Vue.js 牛刀小試】事件修飾符的使用

    • 一、DOM事件流中存在着三個階段:事件捕獲階段、處於目標階段、事件冒泡階段
    • 二、.stop:阻止事件冒泡
    • 三、.prevent:阻止默認事件
    • 四、.capture:添加事件監聽器時使用事件捕獲模式
    • 五、.self:只當在 event.target 是當前元素自身時觸發處理函數
    • 六、.once:事件只觸發一次
    • 七、.passive:滾動事件的默認行爲 (即滾動行爲) 將會當即觸發

11月5號

  • 使用Promises(優)

    • Promise 本質上是一個綁定了回調的對象,而不是將回調傳進函數內部。

    • 在 JavaScript 事件隊列的當前運行完成以前,回調函數永遠不會被調用

    • 經過 .then 形式添加的回調函數,甚至都在異步操做完成以後才被添加的函數,都會被調用

    • 若是想要在回調中獲取上個 Promise 中的結果,上個 Promise 中必需要返回結果

    • 在一個.catch操做以後能夠繼續使用鏈式.then操做

    • 一般遞歸調用一個由異步函數組成的數組時至關於一個 Promise 鏈式:Promise.resolve().then(func1).then(func2)

    • 傳遞到then中的函數被置入了一個微任務隊列,而不是當即執行,這意味着它是在JavaScript事件隊列的全部運行時結束了,事件隊列被清空以後纔開始執行

    • 嵌套的 catch 僅捕捉在其以前同時還必須是其做用域的 failureres,而捕捉不到在其鏈式之外或者其嵌套域之外的 error。

    • 一個好的經驗法則是老是返回或終止 Promise 鏈,而且一旦你獲得一個新的 Promise,返回它。

  • 基於webpack實現react組件的按需加載

    • 實現靜態資源的按需加載,最大程度的減少首頁加載模塊體積和首屏加載時間,其提供的Code Splitting(代碼分割)特性正是實現模塊按需加載的關鍵方式。

    • 將某些第三方基礎框架模塊(例如:moment、loadash)或者多個頁面的公用模塊(js、css)拆分出來獨立打包加載,一般這些模塊改動頻率很低,將其與業務功能模塊拆分出來並行加載,一方面能夠最大限度的利用瀏覽器緩存,另外一方面也能夠大大下降多頁面系統的代碼冗餘度。

    • CommonsChunkPlugin公共基礎庫模塊單獨打包到一個文件中

    • 常用webpack的css-loader來將css樣式導入到js模塊中,再使用style-loader將css樣式以<style>標籤的形式插入到頁面當中,缺點是沒法單獨加載並緩存css樣式文件,頁面展示必須依賴於包含css樣式的js模塊,從而形成頁面閃爍的不佳體驗。

    • 將js模塊當中import的css模塊提取出來,須要用到extract-text-webpack-plugin

    • 使用React動態路由來按需加載react組件

  • 大前端的技術原理和變遷史

    • Web1.0 到 Web2.0過渡的標誌,就是Ajax的出現(2005年)。
    • AJAX 即 Asynchronous JavaScript and XML(異步的 JavaScript 與 XML 技術)
    • SPA 即單頁面,就是頁面總體不刷新,不一樣的頁面只改變局部的內容的一種實現方式。
    • 一個完整的URI有如下幾部分組成:scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment],以上規則中,只有 # 後面的 fragment 發生改變時,頁面不會從新請求,其它參數變化,均會引發頁面的從新請求,而在Js中偏偏還有事件 window.onhashchange 能監聽到 fragment 的變化,因而就利用這個原理來達到一個修改局部內容的操做。#fragment 部分就是對應到Js中的 location.hash 的值。
    • 一個符合前端工程化要求的方案應該包含如下要素:開發規範、模塊化開發、組件化開發、組件倉庫、性能優化、部署、開發流程、開發工具

交流

本人Github連接以下,歡迎各位Star

github.com/yygmind/blo…

我是木易楊,網易高級前端工程師,跟着我每週重點攻克一個前端面試重難點。接下來讓我帶你走進高級前端的世界,在進階的路上,共勉!

若是你想加羣討論每期面試知識點,公衆號回覆[加羣]便可

相關文章
相關標籤/搜索