標籤:擷取 自己的 非同步任務 alt 非同步 機制 主線程 efi llb
最近在讀《JavaScript進階程式設計》這一本書,裡面提到了JavaScript的特徵,倍感興趣,於是結合自己的認識,在這裡進行一下總結。
1、JavaScript的記憶體回收機制
javaScript中的5種資料類型存放在棧中(Undefined、Null、Boolean、Number、String),非基礎資料型別 (Elementary Data Type)存放在堆中,佔用記憶體,堆不會被程式自動釋放。
一張圖看懂JS中資料類型的存放位置:基礎資料型別 (Elementary Data Type)存放在棧中,非基礎資料型別 (Elementary Data Type)存放在堆中(對象),變數obi1在棧中儲存的只是堆中對象的地址。
聲明變數a=對象,只是聲明一個指標地址指向儲存該對象的記憶體空間,每多一個指向同一記憶體空間的指標地址,該對象的引用計數就會加1。
如果代碼在運行過程中有一個對象不再被需要了,但是引用計數不為零,記憶體回收機制就不能釋放這塊記憶體,這就被稱為記憶體流失。
釋放記憶體的方法就是 接觸對該記憶體位址的引用,將引用他的指標地址設定為null,如:a=null;
2、JavaScript 單線程(同一個時間只能做一件事)核心特徵
JS除了主線程之外還存在一個任務隊列,(js單線程所有任務必須排隊完成)。
js計算能力很弱如果存在一個耗時較長的任務,後一個任務就必須等待很長時間讓前一個任務執行完畢,,如果是網路請求他的耗時完全取決於網路狀況,(Ajax)不符合js設計邏輯。
主線程可以忽略io(input/output)裝置,掛起處於等待中的任務(監聽事件綁定的任務,ajax網路請求)先運行排在後面的任務,,等到io裝置有了返回結果,再回過頭把掛起任務執行下去 (非同步事件)。
所有任務分兩種synchronous同步事件asynchronous非同步事件,在js中:
同步事件在主線程上排隊執行(前一個執行完畢,後一個才能執行)。
非同步事件不進入主線程,而進入任務隊列(task queue),只有任務任務隊列通知主線程,某個非同步任務可以執行了,該任務才會從任務隊列中取出進入主線程。
3、JavaScript運行機制步驟
(1)所有同步任務都在主線程上依次執行,形成(執行棧)。棧的定義:先進後出,後進先出。
舉個例子:定義三個函數,sayHello函數直接在student函數體內調用,isAdult函數作為參數傳給了sayHello函數,在這裡isAdult也是一個回呼函數。
三個函數進入執行棧的順序依次是:student,sayHello,isAdult
function student(){ var age = 18; var name = ‘小李‘ sayHello(name,age,isAdult(age)) console.log("student函數") //最後出棧 } function isAdult(age){ var result = age >= 18 ? ‘成年‘:‘未成年‘ console.log("isAdult函數") //最先出棧 return result; } function sayHello(name,age,reust){ console.log(‘hello!This is ‘+name+‘ ‘+age+‘years old 我‘ + reust) console.log("sayHello函數") }
student();
看輸出結果:三個函數進入執行棧的順序依次是:isAdult,student,sayHello
(2)主線程之外,存在一個任務隊列,只要非同步任務有了返回結果,該任務就會被放入任務隊列中。
(3)執行棧中所有任務執行完畢後,就會訪問任務隊列,檢查隊列中有哪些事件,擷取任務隊列中最先等待的事件,讓該事件進入執行棧,開始執行。
(4)不斷重複第三步。
4、JavaScript中回呼函數callback(事件綁定函數)
例:綁定點擊事件,當點擊事件觸發時 js會呼叫事件綁定的函數該函數稱為事件的回呼函數(非同步任務必須指定回呼函數)。
任務隊列 先進先出資料結構,排在前面的事件會先被主線程讀取,所以如果隊列中有‘定時器‘,定時器未必準時觸發,取決於前一個任務隊列中的函數執行的結束。
5、JavaScript中記憶體地區
程式運行時,需要記憶體空間存放資料,分別為stack(棧)和heap(堆)。
棧是有結構的,每個區塊按照一定的順序取存放,可以明確的知道每個區塊的大小,而堆是沒有結構的,資料任意存放,因此棧的調用要快於堆。
每個線程分配一個棧,每個進程分配一個堆,stack是線程獨佔,heap是線程公用的。
棧是系統自動開闢的自動釋放的, 堆是程式員手動開闢和釋放的。
深入理解JavaScript特性