Set、Map、weakSet、WeakMap
Set
1、成員唯一、無序且不重複
2、[value, value],鍵值與鍵名是一致的(或者說只有鍵值,沒有鍵名)
3、可以遍歷,方法有:add、delete、has
WeakSet
1、成員都是物件
2、成員都是弱引用,可以被垃圾回收機制回收,可以用來儲存DOM節點,不容易造成記憶體洩漏
3、不能遍歷,方法有add、delete、has
Map
1、本質上是鍵值對的集合,類似集合
2、可以遍歷,方法很多可以跟各種資料格式轉換
WeakMap
1、只接受物件作為鍵名(null除外),不接受其他型別的值作為鍵名
2、鍵名是弱引用,鍵值可以是任意的,鍵名所指向的物件可以被垃圾回收,此時鍵名是無效的
3、不能遍歷,方法有get、set、has、delete
setTimeout、Promise、Async/Await
經典例題
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout0');
}, 0)
setTimeout(function() {
console.log('setTimeout3');
}, 3)
setImmediate(() => console.log('setImmediate));
process.nextTick(() => console.log('nextTick));
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
console.log('promise2)
}).then(function() {
console.log('promise3');
});
console.log('script end');
複製程式碼
script start --> async1 start --> async2 --> promise1 --> promise2 --> script end --> nextTick --> async1 end --> promise3 --> setTimeout0 --> setImmediate --> setTimeout3
複製程式碼
重繪與迴流
重繪:由於節點的幾何屬性發生改變或者由於樣式發生改變而不會影響佈局的,稱為重繪,例如outline, visibility, color、background-color等,重繪的代價是高昂的,因為瀏覽器必須驗證DOM樹上其他節點元素的可見性。
迴流:迴流是佈局或者幾何屬性需要改變就稱為迴流。迴流是影響瀏覽器效能的關鍵因素,因為其變化涉及到部分頁面(或是整個頁面)的佈局更新。一個元素的迴流可能會導致了其所有子元素以及DOM中緊隨其後的節點、祖先節點元素的隨後的迴流。
減少重繪與迴流
1、CSS
使用 transform 替代 top
使用 visibility 替換 display: none ,因為前者只會引起重繪,後者會引發迴流(改變了佈局)
避免使用table佈局,可能很小的一個小改動會造成整個 table 的重新佈局
儘可能在DOM樹的最末端改變class,迴流是不可避免的,但可以減少其影響。儘可能在DOM樹的最末端改變class,可以限制了迴流的範圍,使其影響儘可能少的節點。
避免設定多層內聯樣式,CSS 選擇符從右往左匹配查詢,避免節點層級過多。
將動畫效果應用到position屬性為absolute或fixed的元素上,避免影響其他元素的佈局,這樣只是一個重繪,而不是迴流,同時,控制動畫速度可以選擇 requestAnimationFrame
避免使用CSS表示式,可能會引發迴流。
將頻繁重繪或者回流的節點設定為圖層,圖層能夠阻止該節點的渲染行為影響別的節點,例如will-change、video、iframe等標籤,瀏覽器會自動將該節點變為圖層。
CSS3 硬體加速(GPU加速),使用css3硬體加速,可以讓transform、opacity、filters這些動畫不會引起迴流重繪 。但是對於動畫的其它屬性,比如background-color這些,還是會引起迴流重繪的,不過它還是可以提升這些動畫的效能。
2、JavaScript
避免頻繁操作樣式,最好一次性重寫style屬性,或者將樣式列表定義為class並一次性更改class屬性。
避免頻繁操作DOM,建立一個documentFragment,在它上面應用所有DOM操作,最後再把它新增到文件中。
避免頻繁讀取會引發迴流/重繪的屬性,如果確實需要多次使用,就用一個變數快取起來。
對具有複雜動畫的元素使用絕對定位,使它脫離文件流,否則會引起父元素及後續元素頻繁迴流。
call 、 apply
1、Function.prototype.apply和Function.prototype.call 的作用是一樣的,區別在於傳入引數的不同;
2、第一個引數都是,指定函式體內this的指向;
3、第二個引數開始不同,apply是傳入帶下標的集合,陣列或者類陣列,apply把它傳給函式作為引數,call從第二個開始傳入的引數是不固定的,都會傳給函式作為引數。
4、call比apply的效能要好,平常可以多用call, call傳入引數的格式正是內部所需要的格式
function 、 () => {}
1、函式體內的 this 物件,就是定義時所在的物件,而不是使用時所在的物件。
2、不可以使用 arguments 物件,該物件在函式體內不存在。如果要用,可以用 rest 引數代替。
3、不可以使用 yield 命令,因此箭頭函式不能用作 Generator 函式。
4、不可以使用 new 命令,因為:
沒有自己的 this,無法呼叫 call,apply。
沒有 prototype 屬性 ,而 new 命令在執行時需要將建構函式的 prototype 賦值給新的物件的 proto
前端加密的常見場景和方法
加密的目的,簡而言之就是將明文轉換為密文、甚至轉換為其他的東西,用來隱藏明文內容本身,防止其他人直接獲取到敏感明文資訊、或者提高其他人獲取到明文資訊的難度。
場景-密碼傳輸
前端密碼傳輸過程中如果不加密,在日誌中就可以拿到使用者的明文密碼,對使用者安全不太負責。 這種加密其實相對比較簡單,可以使用 PlanA-前端加密、後端解密後計算密碼字串的MD5/MD6存入資料庫;也可以 PlanB-直接前端使用一種穩定演算法加密成唯一值、後端直接將加密結果進行MD5/MD6,全程密碼明文不出現在程式中。
PlanA
使用 Base64 / Unicode+1 等方式加密成非明文,後端解開之後再存它的 MD5/MD6 。
PlanB
直接使用 MD5/MD6 之類的方式取 Hash ,讓後端存 Hash 的 Hash 。
場景-資料包加密
全面採用 HTTPS 從手段上來看,它不算是一種前端加密場景;但是從解決問題的角度來看,這確實是前端需要知道的事情。
場景-展示成果加密
反爬技術