深入理解JavaScript特性

來源:互聯網
上載者:User

標籤:擷取   自己的   非同步任務   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特性

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.