透過 Object.observe 回應變更

Alex Danilo

許多使用 MVC 或 MDV 的 JavaScript 架構,都需要針對網頁應用程式內狀態建模的物件做出回應。這項功能是資料繫結模型的基本部分。

監控 JavaScript 物件與 DOM 屬性有多種方式可觸發某些動作,但大部分的技巧都不是因為效能等各種原因而不適用。

為了提升網頁應用程式的效能,TC39 已經提議使用名為 Object.observe() 的新方法,該方法旨在監督 ECMAScript (JavaScript) 的開發。

Object.observe() 可讓您將事件監聽器新增到每次該物件或其屬性變更時呼叫的 JavaScript 物件。

您現在可以在 Chrome Canary 25 中試用這項功能。

如要體驗這項功能,您必須在 Chrome Canary 中啟用「啟用實驗性 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 屬性可識別物件發生情況。以下程式碼中會顯示一些設定屬性和關聯的 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 標準內文是尋求對這項功能的意見回饋,歡迎加以測試,並告訴我們您的想法。