1.Javascript延遲加載有哪些方式
-
瀏覽器解析html全過程
- 解析HTML結構
- 遇到script腳本標籤(無async,defer)直接執行,或者加載,並且執行script(會阻塞HTML)
- 解析並執行完腳本
- Dom樹構建完成,加載圖片等外部資源
- 加載結束
-
延遲加載或者異步加載有什麼作用
- 不阻塞HTML解析,用戶體驗更好
-
具體有哪些異步(延遲)加載Javascript的方式
- 外部script標籤 增加
async
標籤或者defer
標籤- 相同點是都可以不阻塞html解析
- 不同點是:defer是
延遲執行
而async
是異步加載,defer
會確保在html解析完畢之後再按defer
順序執行js,而async
是異步加載,加載完成之後,會直接執行js
,並且執行時,此時會阻塞HTML
解析
- 使用js,create
Script
標籤,並且可以設置延遲加載 - 因爲
HTML
的解析是自上而下的,所以把script
標籤放到最後面,也會使js
在最後加載,也是很多頁面js
標籤寫在最後優化體驗的最簡單的方式
- 外部script標籤 增加
2.call和apply的區別和作用?
-
作用:改變
this
(函數內部上下文)指向,很多函數內部會直接使用this
指針,指向內部自身對象,並且進行一系列操作,但是如果希望用另一個對象作爲該函數的上下文時就需要用到call
和apply
-
相同點:
- 都可以用來改變函數
this
(函數內部上下文)指向 - 第一個參數,都是上下文入參
- 都屬於
Function.prototype
,所有函數類方法 - 如果第一個參數爲
null
時,函數體內部this
指向默認上下文,可能是window
- 都可以用來改變函數
-
不同點
- 除了第一個參數外,後面的參數:都是傳入原函數的入參,但是
入參接收形式
不一樣,apply 後面接收的是一個
類數組,而call接受的後面參數是單個的參數會原封的傳入原函數
- 除了第一個參數外,後面的參數:都是傳入原函數的入參,但是
-
ES6語法的
...
延展語法,可以更方便的使用call,數組也可以直接解構function.call(obj,...[arry])
3. 哪些操作會造成內存泄漏
-
什麼是內存泄漏
- 指代碼執行時,變量或者代碼語句分配的內存空間,無法被自動回收,也不能被繼續使用,一直到該進程結束
-
JS中的垃圾回收機制
GC
garbage collection,自動執行,定時執行,- 引用計數: 變量進入環境時(一般是函數作用域),進入環境時,增加標記,環境執行之後,離開環境,標記爲:離開環境,變量被回收
- 標記清除:根據變量被引用次數計數,被引用一次+1,移除引用-1,爲0時表示沒有變量訪問該值,可以被清理
-
那些操作會造成內存泄漏
- 函數內部聲明的全局變量
function(){ test = xxx }
- 閉包導致的引用計數無法被清除
- 沒有清除的DOM元素引用
- 忘記clear的定時器和回調
- DOM元素獲取時,子元素的引用(在獲取DOM節點時,在直接操作子元素時,父元素也會被內存加載,但是並不會被自動回收,或者經常忘記回收)
- 函數內部聲明的全局變量