ECMAScript
規定了JavaScript
腳本的核心語法,如 數據類型、關鍵字、保留字、運算符、對象和語句等,它不屬於任何瀏覽器。javascript
文檔對象模型(DOM
)將web
頁面與到腳本或編程語言鏈接起來。一般是指 JavaScript
,但將HTML
、SVG
或XML
文檔建模爲對象並非JavaScript
語言的一部分。DOM
模型用一個邏輯樹來表示一個文檔,樹的每一個分支的終點都是一個節點(node
),每一個節點都包含着對象(objects
)。DOM
的方法(methods
)讓你能夠用特定方式操做這個樹,用這些方法你能夠改變文檔的結構、樣式或者內容。節點能夠關聯上事件處理器,一旦某一事件被觸發了,那些事件處理器就會被執行。java
瀏覽器對象模型(BOM
),是用於描述這種對象與對象之間層次關係的模型,瀏覽器對象模型提供了獨立於內容的、能夠與瀏覽器窗口進行互動的對象結構。BOM
由多個對象組成,其中表明瀏覽器窗口的Window
對象是BOM
的頂層對象,其餘對象都是該對象的子對象.node
進程(Process
)是系統資源分配和調度的單元。一個運行着的程序就對應了一個進程。一個進程包括了運行中的程序和程序所使用到的內存和系統資源。若是是單核CPU
的話,在同一時間內,有且只有一個進程在運行。可是,單核CPU
也能實現多任務同時運行,好比你邊聽網易雲音樂的每日推薦歌曲,邊在網易有道雲筆記上寫博文。這算開了兩個進程(多進程),那運行的機制就是一下子播放一下歌,一下子響應一下你的打字,但因爲CPU
切換的速度很快,你根本感受不到,以致於你認爲這兩個進程是在同時運行的。進程之間是資源隔離的。web
那線程(Thread
)是什麼?線程是進程下的執行者,一個進程至少會開啓一個線程(主線程),也能夠開啓多個線程。好比網易雲音樂一邊播放音頻,一邊顯示歌詞。多進程的運行其實也就是經過進程中的線程來執行的。一個進程下的線程是能夠共享資源的,因此在多線程的狀況下,須要特別注意對臨界資源的訪問控制.算法
目前最爲流行的瀏覽器爲:`Chrome,IE,Safari,FireFox,Opera.
一個瀏覽器一般由如下幾個常駐的線程:
JS
引擎線程:負責JS
的解析和執行setTimeout
, setInterval
DOM
事件http
請求線程:處理http
請求須要注意的是,渲染線程和JS
引擎線程是不能同時進行的。渲染線程在執行任務的時候,JS
引擎線程會被掛起。由於JS
能夠操做DOM,若在渲染中JS
處理了DOM
,瀏覽器可能就懵逼了。
Web Worker
(工做線程) 是 HTML5
中提出的概念,Web Workers
使得一個Web
應用程序能夠在與主執行線程分離的後臺線程中運行一個腳本操做。這樣作的好處是能夠在一個單獨的線程中執行費時的處理任務,從而容許主(一般是UI
)線程運行而不被阻塞/放慢.編程
Web Worker
能夠分爲一下幾類:canvas
Dedicated Worker
)專用線程僅能被建立它的腳本所使用(一個專用線程對應一個主線程)
Shared Worker
)共享線程可以在不一樣的腳本中使用(一個共享線程對應多個主線程)
Service Workers
)
註冊在指定源和路徑下的事件驅動
worker
, 能夠控制關聯的頁面或者網站,攔截並修改訪問和資源請求,細粒度地緩存資源.
Chrome Workers
一種僅適用於firefox
的worker
.
Aduio Workers
能夠在網絡
worker
上下文中直接完成腳本化音頻處理
能夠經過 caniuse 查看兼容性
Dedicated Worker
兼容性
Shared Worker
兼容性
canvas
圖形繪製DOM
Window
對象workerType | 上下文 |
---|---|
Dedicated Worker | DedicatedWorkerGlobalScope |
Shared Worker | SharedWorkerGlobalScope |
if (window.Worker) { // some code }
@params {String} url 表示worker將執行的腳本的URL,必須遵照同源策略 @params {Object} [options] 建立對象實例時設置的選項屬性的對象 @params {Object} [options.type] @params {Object} [options.name] @params {Object} [options.credentials] @returns 建立的worker const myWorker = new Worker(url[, options]);
// main.js const myDedicatedWorker = new Worker('./dedicated_worker/worker.js', { name: 'dedicatedWorker' }); // worker.js console.log('success');
@params {String} url 表示worker將執行的腳本的URL,必須遵照同源策略 @params {Object} [options] 建立對象實例時設置的選項屬性的對象 @params {Object} [options.type] @params {Object} [options.name] @params {Object} [options.credentials] @returns 建立的worker const myWorker = new SharedWorker(url[, options]);
// main.js const mySharedWorker = new SharedWorker('./shared_worker/worker.js', { name: 'sharedWorker' }); // worker.js console.log('success');
@params {Object} message 傳遞的數據對象 @params {Object} [options] 一個可選的Transferable對象的數組,用於傳遞全部權.若是一個對象的全部權被轉移,在發送它的上下文中將變爲不可用(停止),而且只有在它被髮送到的worker中可用。 myWorker.postMessage(message, transferList);
myWorker.onmessage = function(event) { const data = event.data; // 接收到的消息數據 }
// main.js const myWorker = new Worker('worker.js'); myWorker.postMessage([10, 20]); myWorker.onmessage = function (event) { console.log(event.data); } // worker.js onmessage(event) { console.log(event.data); postMessage(event.data[1] - event.data[0]); }
// main.js const myWorker = new SharedWorker('worker.js'); myWorker.port.start(); myWorker.port.postMessage([10, 20]); myWorker.port.onmessage = function (event) { console.log(event.data); } // worker.js connect(event) { const port = event.port[0]; port.onmessage(event) { port.postMessage(event.data[1] - event.data[0]); } }
在SharedWorker
的使用中,咱們發現對於SharedWorker
實例對象,咱們須要經過port
屬性來訪問到主要方法;同時在Worker
腳本中,多了個全局的connect()
函數,同時在函數中也須要去獲取一個port
對象來進行啓動以及操做;這是由於,多頁頁面共享一個SharedWorker
線程時,在線程中須要去判斷和區,分來自不一樣頁面的信息,這是最主要的區別和緣由。在
Worker
線程中,self
和this
都表明子線程的全局對象。對於監聽message
事件,如下的四種寫法是等同的。數組
// 寫法 1 self.addEventListener('message', function (e) { // ... }) // 寫法 2 this.addEventListener('message', function (e) { // ... }) // 寫法 3 addEventListener('message', function (e) { // ... }) // 寫法 4 onmessage = function (e) { // ... }
myWorker.terminate(); // 主線程中使用
close(); worker線程中使用(推薦)
// 主線程 myWorker.onerror = function(event) { const lineno = event.lineno; // 出錯的腳本名稱 const filename = event.filename; // 發生錯誤的行號 const message = event.message; // 對錯誤的描述 }
// 不能進行反序列化時觸發 myWorker.onmessageerror = function() { ... } // 專用線程 myWorker.port.onmessageerror function() {...} // 共享線程
提供importScript()
方法,導入一條或者以上腳本到當前worker
的做用域裏.
每一個腳本中的全局對象都可以被 worker 使用.
importScript('first.js', 'second.js');
Worker
能夠生成子進程瀏覽器
Worker
中的URL
相對於父級Woker
所在位置進行解析<script type="text/js-worker"> onmessage = (event) => { postMessage(event.data + 1); } </script> <script> const workerScript = document.querySelector('script[type="text/js-worker"]'); const blob = new Bolb(workerScript, { type: 'text/javascript' }); const myWorker = new Worker(window.URL.createObjectURL(blob)); myWorker.postMessage(1); myWorker.onmessage = (event) => { console.log('來自子線程消息:', event.data); } </script>
結構化克隆算法是由HTML5
規範定義的用於複製複雜JavaScript
對象的算法。經過來自Workers
的postMessage()
或使用IndexedDB
存儲對象時在內部使用。它經過遞歸輸入對象來構建克隆,同時保持先前訪問過的引用的映射,以免無限遍歷循環。這一過程能夠理解爲,在發送方使用相似JSON.stringfy()
的方法將參數序列化,在接收方採用類JSON.parse()
的方法反序列化。
Error
以及Function
對象是不能被結構化克隆算法複製的;若是你嘗試這樣子去作,這會致使拋出DATA_CLONE_ERR
的異常DOM
對象的某些特定參數也不會被保留緩存
RegExp
對象的lastIndex
字段不會被保留Web Worker
中可使用的函數和類clearInterval() clearTimeout() setInterval() setTimeout
Worker
相關importScripts() close() postMessage()
Cache IndexedDB
Fetch WebSocket XMLHttpRequest