更新:謝謝你們的支持,最近折騰了一個博客官網出來,方便你們系統閱讀,後續會有更多內容和更多優化,猛戳這裏查看javascript
------ 如下是正文 ------css
這裏分享過去一週高級前端進階羣裏的學習彙總,天天會在羣裏給你們發一些資料一塊兒學習,晚上會上傳個人筆記,內容之前端基礎、源碼分析、面試題解爲主,若是你上班沒時間看,那週末能夠好好學習了,彎道超車重在堅持。html
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 Binding。2)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
的狀況下)或保持未初始化(在 let
和 const
的狀況下)。因此這就是爲何能夠在聲明以前訪問 var
定義的變量(儘管是 undefined
),但若是在聲明以前訪問 let
和 const
定義的變量就會提示引用錯誤的緣由。這就是所謂的變量提高。
若是 Javascript 引擎在源代碼中聲明的實際位置找不到 let
變量的值,那麼將爲其分配 undefined
值。
對於 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
複製代碼
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 的值,而後返回該值。
場景:有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
})
複製代碼
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); 複製代碼
SyntheticEvent
採用了池的思想,從而達到節約內存,避免頻繁的建立和銷燬事件對象的目的。setState
)React都會將中間過程保存起來,留到最後面才flush掉。setState
還未最終被commit到DOM樹上,這時須要把第一次按鈕的結果先給flush掉並commit到DOM樹,纔可以保持一致性。ES6 系列之 Babel 是如何編譯 Class 的(上)
一、ES5 的構造函數對應 ES6 的constructor 方法。
二、ES6定義的全部方法,都是不可枚舉的。
三、在方法前加上 static 關鍵字不會被實例繼承,是直接經過類來調用,這個是"靜態方法"。
四、類和普通構造函數的一個主要區別是類必須使用 new 調用,不然會報錯。
五、使用 get 和 set 關鍵字攔截屬性默認行爲
六、Babel 轉換經過_classCallCheck檢查類是不是經過 new 的方式調用
七、靜態屬性static bar = 'bar'
轉換成Person.bar = 'bar'
八、Babel 生成了一個 _createClass 輔助函數,該函數傳入三個參數,第一個是構造函數,在這個例子中也就是 Person,第二個是要添加到原型上的函數數組,第三個是要添加到構造函數自己的函數數組,也就是全部添加 static 關鍵字的函數。該函數的做用就是將函數數組中的方法添加到構造函數或者構造函數的原型中,最後返回這個構造函數。
使用Promises(優)
Promise 本質上是一個綁定了回調的對象,而不是將回調傳進函數內部。
在 JavaScript 事件隊列的當前運行完成以前,回調函數永遠不會被調用
經過 .then 形式添加的回調函數,甚至都在異步操做完成以後才被添加的函數,都會被調用
若是想要在回調中獲取上個 Promise 中的結果,上個 Promise 中必需要返回結果
在一個.catch
操做以後能夠繼續使用鏈式.then
操做
一般遞歸調用一個由異步函數組成的數組時至關於一個 Promise 鏈式:Promise.resolve().then(func1).then(func2)
傳遞到then中的函數被置入了一個微任務隊列,而不是當即執行,這意味着它是在JavaScript事件隊列的全部運行時結束了,事件隊列被清空以後纔開始執行
嵌套的 catch 僅捕捉在其以前同時還必須是其做用域的 failureres,而捕捉不到在其鏈式之外或者其嵌套域之外的 error。
一個好的經驗法則是老是返回或終止 Promise 鏈,而且一旦你獲得一個新的 Promise,返回它。
實現靜態資源的按需加載,最大程度的減少首頁加載模塊體積和首屏加載時間,其提供的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組件
scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
,以上規則中,只有 #
後面的 fragment
發生改變時,頁面不會從新請求,其它參數變化,均會引發頁面的從新請求,而在Js中偏偏還有事件 window.onhashchange
能監聽到 fragment
的變化,因而就利用這個原理來達到一個修改局部內容的操做。#fragment
部分就是對應到Js中的 location.hash
的值。本人Github連接以下,歡迎各位Star
我是木易楊,網易高級前端工程師,跟着我每週重點攻克一個前端面試重難點。接下來讓我帶你走進高級前端的世界,在進階的路上,共勉!
若是你想加羣討論每期面試知識點,公衆號回覆[加羣]便可