ECMAScript中的對象和DOM BOM對象是一個概念么?


一個概念。

前幾天做了一個 JavaScript 內置對象的思維導圖,justjavac/programming-mindmap。

DOM 和 BOM 並不屬於 JavaScript(ECMAScript ) 語言的一部分。DOM 和 BOM 是 JavaScript 的運行平台(瀏覽器)提供的,比如在 nodejs 中就沒有 DOM 和 BOM。

JavaScript 類型分為 2 大類:原生類型和對象類型。而 DOM 和 BOM 都是對象類型。

比如 html 中的段落 p 映射為 JavaScript 對象是 HTMLParagraphElement,顧名思義 Paragraph 就是英語「段落」的意思。

我們看看 HTMLParagraphElement 的繼承關係:

HTMLParagraphElement
- HTMLElement
- Element
- Node
- EventTarget
- Object

所有的 DOM 和 BOM 沒有任何特殊之處,都是一個 Object 的子類。

var div = document.createElement("div"); // 創建一個 div dom
div.foo = 1234; // 給 div 添加屬性
div.sayHello = function(str) {
console.log("hello " + str);
}

當我們創建了一個 DOM Object 後,我們就可以把這個 DOM Object 當作一個普通的 JavaScript 對象來使用。

說他特殊,大概是因為 DOM 的屬性和方法會被引擎映射到 html 標籤上。有些會,有些不會,有些只能從 html 到 dom 映射,有些只能從 dom 到 html 映射。這個得需要一篇單獨的文章來講了。。。

我先挖個坑,再來慢慢講 HTML attribute 和 DOM property · Issue #15


如果但從對象的角度講,特殊的不是 DOM 和 BOM,而是另一個值:

Object.create(null);

所有的 JavaScript 對象都是繼承自 Object,即使我們經常創建的空對象:

let obj = {};

也是 Object 的子類。

但是 Object.create(null) 卻是實實在在的空對象:


既然講到這兒了,就再補充點知識點。

在引擎(V8)內部,DOM 對象映射為 C++ Object:

而每個 html 標籤都對應一個 DOM Object。

我們看如下代碼:

var div = document.createElement("div"); // 創建一個 div dom
div.foo = 1234; // 給 div 添加屬性
var p = document.createElement("p"); // 創建一個 p dom
p.appendChild(div); // 把 div 添加為 p 的子節點
div = null; // div 設置為空
console.log(p.firstChild.foo);

可能我們會覺得最終輸出的是 null、或者 undefined、或者拋異常。

其實這行代碼會輸出 1234。


DOM 如何與 JavaScript Object 關聯在一起的規範定義在 WebIDL Level 1,WEBIDL 就是 Web Interface Definition Language 的縮寫。

如無特殊說明,後面的文章都是以 V8 引擎為例。

DOM Object 在引擎內部是一個 C++ Object,當 JavaScript 操作這個 DOM 時,引擎使用一個 wrapper object,也就是 JavaScript Object。

Wrapper Object 和 DOM Object 的關係是 n : 1(n &>= 0)

  • 當 n == 0 時,此 DOM Object 不能通過 JavaScript 訪問
  • 當 n == 1 時,此 DOM Object 只有一個 JavaScript Object 可以訪問
  • 當 n &> 1 時,此 DOM Object 可以通過多個 JavaScript 訪問

舉個例子:

div = document.createElement("div");
div.innerHTML = "&

&foo&&&";
div.firstChild;

上面代碼的對應關係圖:

有點文不對題了,再開一個坑吧 DOM Object 和 JavaScript Object · Issue #16


不是,dom是文檔對象模型,操作的是html文檔的內容,比如修改文字顏色,修改div元素寬高等

bom是瀏覽器對象模型,操作的是瀏覽器,比如頁面跳轉,頁面前進或者後退等


是一回事,這個是框架層的事

ecma只是一套標準,是針對js解釋器的規範

dom和bom是在分配內存之後生成的結構,然後通過w3c的標準介面來進行調用


DOM 和 BOM 這種庫層面的東西,如果要讓 ECMAScript 這種語言調用,必然要封裝成它的對象的形式。


推薦閱讀:

那些你不知道的爬蟲反爬蟲套路
寫給在迷茫中前行的前端學習/工作者
解鎖緩存新姿勢——更靈活的 Cache
首屆螞蟻金服體驗科技大會
「小白DAY7」細談設計稿還原

TAG:前端開發 | 面向對象編程 |