透過 Object.observe 回應變更

Alex Danilo

許多使用 MVC 或 MDV 的 JavaScript 架構都需要回應物件變更,這些物件會模擬網路應用程式中的狀態。這項功能是資料繫結模型的基本部分。

監控 JavaScript 物件和 DOM 屬性以觸發某些動作的方法有很多種,但大多數的做法都因效能等因素而不適合。

為改善網頁應用程式的效能,我們已向 TC39 (負責監督 ECMAScript (JavaScript) 開發工作的標準機構) 提出名為 Object.observe() 的新方法。

您可以使用 Object.observe() 在任何 JavaScript 物件中新增事件監聽器,以便在該物件或其屬性變更時呼叫該監聽器。

您現在可以試用 Chrome Canary 25 版。

如要試用這項功能,請在 Chrome Canary 中啟用「Enable Experimental JavaScript」標記,然後重新啟動瀏覽器。旗幟位於「about:flags」下方,如下圖所示:

Chrome 旗標。

以下是如何在物件上設定觀察器的簡單範例:

var beingWatched = {};
// Define callback function to get notified on changes
function somethingChanged(changes) {
    // do something
}
Object.observe(beingWatched, somethingChanged);

當物件「beingWatched」經過修改時,系統會觸發回呼函式「somethingChanged」,接收套用至物件的變更陣列。

因此,JavaScript 引擎可以自由地緩衝多項變更,並在單一回呼函式呼叫中傳遞所有變更。這有助於最佳化回呼,讓程式碼可以執行大量 JavaScript 操作,但只處理少數回呼,因為更新會一起批次處理。

每當新增、修改、刪除或重新設定屬性時,系統都會觸發回呼函式。

觀察陣列時,另一個非常實用的功能是,如果陣列經過多次變更,您可以使用變更摘要輔助程式庫建立最小變更集,這樣用戶端 JavaScript 就不需要手動掃描陣列,以便檢查每個項目。

您可以輕鬆地逐一檢視每個變更,方法是在「somethingChanged」回呼函式中執行以下操作:

function whatHappened(change) {
    console.log(change.name + " was " + change.type + " and is now " + change.object[change.name]);
}
function somethingChanged(changes) {
    changes.forEach(whatHappened);
}

type 屬性可識別物件發生的事件。以下程式碼列出了一些設定的屬性範例,以及相關的類型

beingWatched.a = "foo"; // new
beingWatched.a = "bar"; // updated
beingWatched.a = "bar"; // no change
beingWatched.b = "amazing"; // new

這項技術的優點在於,所有監控智慧功能都位於 JavaScript 引擎中,因此瀏覽器可妥善進行最佳化,讓 JavaScript 能夠實作功能,充分利用這項功能。

另一個非常實用的開發功能,是能夠在物件變更時使用 Object.observe() 觸發偵錯工具。如要這麼做,請使用類似下方範例的程式碼。

Object.observe(beingWatched, function(){ debugger; });

以下是 Object.observe() 的精彩影片介紹,詳細說明相關內容。

此外,您也可以參考這篇說明文章這裡的實例

TC39 標準機構正在收集這項功能的意見回饋,歡迎試用並與我們分享你的想法。