天天看點

圖解JavaScript

JavaScript是web前端開發的必備技能之一,在如今各種JS架構滿天飛,我們如何選擇并應用成了困擾,而且最頭疼的是那麼多浏覽器與那麼多的版本讓應用的相容性也成了前端的難題。本文是我對JS學習與工作使用的一個總結,從理論的角度剖析JS。

由于web開發中JS是運作在浏覽器中的,而浏覽器會提供一個API的形式讓JS可以通路到一些屬性,就樣就産生了浏覽器對象模型,包括視窗、通路記錄、顯示屏、浏覽器、目前通路位址等相關資訊,如下:

Window對象是JS中的頂級對象,window是其引用,JavaScript是一個純粹的面向對象語言,在JS中一切皆對象,JS對象有一種專用的描述形式:JSON,JSON如今在其他語言中也變的通用了。window中對其他的BOM又有了引用,例如對Location的引用:window.location,如果我們想改變目前位址,隻要給location的href重新指派就可以了,因為location是Location的引用,而Location代表的就是目前通路位址。

對于一個iframe其實也是一個window對象,而iframe的parent則是iframe外的視窗的引用,有關window的引用關系如圖:

Document對象是視窗中的頁面對象,在JS中對應成了文檔,因為是XML的形式,Document對象其實是一棵樹,裡頁包含了所有頁面元素相關的,JS可以通過Document對象來操作頁面,document是Document的引用,document是window的屬性,是以可以通過window.document來通路對象的屬性及方法。document裡是一個個的element(元素),每個element又包含了很多attribute,每個attribute又包含了name和value。我們平常在頁面上見到的a閉合标簽、div閉合标簽就是element對象,a标簽裡的href就是一個attribute,name是href,value就是URL。如圖是Chrome43浏覽器中從console中看的document對象:

一個element中包含了許多屬性,如圖是一個a标簽裡的一些屬性:

圖解JavaScript

浏覽器在生成文檔對象時會經過不同的狀态,如圖是我手動抓取的,但還有兩個狀态由于時間持續很短沒能抓取到:

圖解JavaScript

實際的狀态流轉是:

對于想要延遲加載的内容,可以通過監聽document的狀态變化來實作。

目前比較流行的JS架構中的Jquery裡的核心功能就是選擇器,這些選擇器是如何實作的呢,以jquery-1.8.2.js為例,我們看源碼:

圖解JavaScript

使用的document的getElementById的方法,由于ID是唯一的,是以這個方法查詢的效率相對其他方法更快些,還有哪些方法?

圖解JavaScript

getElementByClassName這個方法在IE8及以下是沒有的,運作時你會發現如下的錯誤:

圖解JavaScript

樣式表在document裡是什麼樣的呢?首先來看各元素是什麼樣子的吧:

圖解JavaScript

可以看出一個很明顯的樹狀結構,我們來看一下body的樣式,其實是一個樣式數組:

圖解JavaScript

而這些樣式名又對應規則樹中具體的規則,樣式規則樹如圖:

圖解JavaScript

原生的事件是每個element裡面的屬性,如圖是一個img元素的onerror屬性,也就是圖檔下載下傳失敗的處理事件:

圖解JavaScript

可以看到這個事件的處理函數的最下面有一個<function scope>,這是function的作用域鍊,裡面包括了各個作用域,作用域其實也是對象,包括element對象,圖中可以看出的作用域有img、window、document,還有一個Closure(閉包),Closure是JS中為了保證變量在其他地方引用時不被垃圾回收的一種機制,通常是一個function就是一個Closure。說到JS的對象回收機制,和引用有關,但也不是有引用了就不回收,例如孤島對象,當然沒被引用的是要回收的。

JS的事件傳播機制:事件冒泡機制,如圖:

圖解JavaScript

子樹結點上的事件會一直往上傳播,除非我們用stopPropagation方法阻止不再傳播,有這麼個情況,如果在a标簽綁定了某類型事件的處理,在父結點的div上又綁了一個同類型,如果在a上執行完不阻止的話,在div上就會又執行一次,造成了多次執行的後果。然而這種傳播機制又有另一種好處,就是事件可以委托給上級處理,這樣綁定事件處理函數時隻需要綁定在上級對象上,新增子結點時事件的處理同樣生效,就不用對新增的結點再綁定了,很多JS架構也是這麼做的。

可以看到每個對象都有一個prototype屬性,打開看下原來是指向父對象的,這其實是JS裡的繼承,而prototype其實是對父對象的引用。

目前流行的JS架構越來越多,以選擇器為核心的Jquery,還有根本看不到選擇器的Angular,類似Angular的Avalon,Jquery就不多說了,來看下Angular吧,先看下在HTML怎麼用的:

圖解JavaScript

我框起來的部分其實在JS檔案裡都有對應的,這一個表單送出,如果用Jquery是會有用選擇器的,但是在JS裡卻看不到選擇器:

圖解JavaScript

上手還是挺簡單的,代碼量也少,代碼也比較清晰,也便于維護,類似的架構還有很多。

從我的角度來說,架構其實是一種工具,對于手機HTML5中我們還是要對架構的大小多慎重的,比如在手機上用Zepto肯定比用JQuery要好,Zepto相容JQuery,但體積小很多,Zepto裁減了很多H5并不用的功能。

往後發展,架構肯定是往更加精細的子產品發展,拆的更多更具有針對性,用了才加載,更加輕量。

繼續閱讀