【JavaScript】Object.observe()帶來的數據綁定變革

enter image description here

Object.observe()帶來的數據綁定變革

引言

一場變革即將到來。一項Javascript中的新特性將會改變你對於數據綁定的全部認識。它也將改變你所使用的MVC庫觀察模型中發生的修改以及更新的實現方式。你會看到,那些全部在乎屬性觀察的應用性能將會獲得巨大的提高。javascript

咱們很高興的看到,Object.observe()已經正式加入到了Chrome 36 beta版本中。php

Object.observe()是將來ECMAScript標準之一,它是一個能夠異步觀察Javascript中對象變化的方法,而無需你去使用一個其餘的JS庫。它容許一個觀察者接收一個按照時間排序的變化記錄序列,這個序列描述的是一列被觀察的對象所發生的變化。html

// 假設咱們有一個模型來存儲數據 var model = {};  // 而後咱們對他進行觀察 Object.observe(model, function(changes){  // 這個異步毀掉函數將會運行 changes.forEach(function(change) {  // 讓咱們獲知變化 console.log(change.type, change.name, change.oldValue); }); }); 

當被觀察的對象發生任何變化時,回調函數將會彙報這些變化:html5

經過使用Object.observe(),你能夠不須要使用任何框架就能實現雙向數據綁定。java

但這並不意味着你就不該該使用一個框架。對於一些有着複雜業務邏輯的項目,通過精心設計的框架的重要性不言而喻,你應該繼續使用它們。這些框架減輕了開發新手的工做量,並且只須要編寫不多的代碼就可以維護和實現一些模式並達到咱們想要的目的。若是你不須要一個框架,你可使用一個體積更小,針對性更強的庫,好比Polymer(它已經開始使用Object.observe()了)。web

即使你已經重度依賴於一個MV*框架,Object.observe()任然能爲你的應用帶來一些性嫩各方面的提高,它可以更快更簡單的實現一些功能並維持一樣的API。例如,在Angular的一個Benchmark測試中,對於一個Model中發生的變化,髒值檢查對每次更新會花費40ms,而Object.observe()只會花費1-2ms(至關於20-40倍的性能提高)。算法

不須要冗長代碼來實現的數據雙向綁定還意味着你不須要經過輪詢來發現變化,這將帶來更長的電池使用時間!數組

若是你已經對Object.observe()有了一些瞭解,能夠直接跳過簡介這一節,或者接着閱讀了解更多關於它可以解決的問題。瀏覽器

咱們想要觀察什麼

當咱們在討論數據觀察時,咱們一般指的是對一些特定類型的數據變化保持關注:緩存

  • 原始JavaScript對象中的變化
  • 當屬性被添加、改變、或者刪除時的變化
  • 當數組中的元素被添加或者刪除時的變化
  • 對象的原型發生的變化

數據綁定的重要性

當你開始關心模型-視圖的控制分離時,數據綁定就會變成一件重要的事。HTML是一個很是好的聲明機制,可是它徹底是靜態的。理想狀態下,你想要在數據和DOM之間聲明它們的關係,以便讓DOM保持更新。這可讓你剩下不少時間來編寫重複來代碼在DOM和應用內部或者服務器端請求或者發送數據。

當你擁有一個複雜的用戶界面,你須要理清楚許多數據屬性和許多視圖中元素的關係時,數據綁定是很是有用的。這在咱們今天須要建立的單頁應用中很是常見。

經過在瀏覽器中原生的觀察數據,咱們給予了JavaScript框架(或者你編寫的一些功能庫)一種方式來實現對模型數據的變化進行觀察而不須要依賴於咱們今天正在使用的一些hack方法。

今天的世界看起來是怎樣的

髒值檢查

你之前曾經在那裏看到過數據綁定?若是你在你的web應用中使用過一個現代MV*框架(例如Angular,Knockout),那麼你或許已經使用過數據綁定將數據綁定到你的DOM上了。爲了複習一下,下面是一個電話列表應用的例子,在其中咱們會將一個phones數組中的值(在JavaScript中定義)綁定到一個列表項目中以便於咱們的數據和UI保持同步:

<html ng-app> <head> ... <script src="angular.js"></script> <script src="controller.js"></script> </head> <body ng-controller="PhoneListCtrl"> <ul> <li ng-repeat="phone in phones"> {{phone.name}} <p>{{phone.snippet}}</p> </li> </ul> </body> </html> 

咱們的JavaScript代碼這樣寫:

var phonecatApp = angular.module('phonecatApp', []); phonecatApp.controller('PhoneListCtrl', function($scope) { $scope.phones = [ {'name': 'Nexus S', 'snippet': 'Fast just got faster with Nexus S.'}, {'name': 'Motorola XOOM with Wi-Fi', 'snippet': 'The Next, Next Generation tablet.'}, {'name': 'MOTOROLA XOOM', 'snippet': 'The Next, Next Generation tablet.'} ]; }); 

任什麼時候候只要是底層的model數據發生了變化,咱們在DOM中的列表也會跟着更新。Angular是怎麼作到這一點的呢?在Angular的背後,有一個叫作髒值檢查的東西。

髒值檢查的基本原理就是隻要任什麼時候候數據發生了變化,這個庫都會經過一個digest或者change cycle去檢查變化是否發生了。在Angular中,一個digest循環意味着全部全部被監視的表達式都會被循環一遍以便查看其中是否有變化發生。它智鬥一個模型以前的值所以當變化發生時,一個change事件將會被觸發。對於開發者來講,這帶來的一大好處就是你可使用原生的JavaScript對象數據,它易於使用及整合。下面的圖片展現的是一個很是糟糕的算法,它的開銷很是大。

這個操做的開銷和被監視的對象的數量是成正比的。我可能須要作不少的髒治檢查。同時我也須要一種方式去觸發髒值檢查,當某些數據可能發生改變時。有不少的框架使用了一些很是聰明的方法來解決這個問題,可是它們是否足夠好目前還尚無定論。

web生態系統應該擁有更多的能力去創新和進化它本身的聲明機制,例如:

  • 有約束的模型系統
  • 自動的保存系統(例如:將變化保存在IndexedDB或者localStorage中)
  • 容器對象(Ember,Backbone)

容器對象是一個框架建立的對象,它可以在其中保存一些數據。它們擁有一些存取器去獲取數據而且可以在你設置或者獲取對象時捕獲到這些行爲並在內部進行廣播。這是一種很是好的方式。它的性能很好,從算法上來講也不錯。下面是一個使用Ember容器對象的一個簡單例子:

// 容器對象 MyApp.president = Ember.Object.create({ name: "Barak Obama" });

MyApp.country = Ember.Object.create({ //使用Binding去建立一個屬性以便告訴Ember建立一個到presidentName屬性的綁定 presidentNameBinding: "MyApp.president.name" });

// 而後,Ember會解析綁定 MyApp.country.get("presidentName"); // "Barack Obama"

//來自服務器的數據須要被如今的代碼轉換整合

在上面的例子中,發現什麼地方發生了變化的開銷和發生改變的東西有着直接聯繫。如今你存在的另外一個問題是你須要使用不一樣種類的對象。總的來講你須要將從服務器獲取的數據進行轉換以便它們是可以被觀察到的。

目前的JS代碼並不能很好的整合生成數據,由於這些代碼通常會假設它們操做的是原生JavaScript對象,而不是一些特定的對象相似類型。

介紹Object.observe()

咱們真正想要的多是兩個世界中最好的東西 – 一種支持對原生數據對象(普通JavaScript對象)進行觀察的方法,同時不須要每次都對全部東西進行髒值檢查。它須要有良好的算法表現。它還須要可以很好的整合到各個平臺中。這些都是Object.observe()可以帶給咱們的東西。

它容許咱們對一個對象或者變異屬性進行觀察,而且在變化發生時獲得及時通知。可是咱們在這裏不想看什麼理論,讓咱們來看看代碼!

Object.observe()和Object.unobserve()

讓咱們假設咱們如今有一個簡單的JavaScript對象,它表明一個模型:

// 一個模型多是一個簡單的JavaScript對象 var todoModel = { label: 'Default', completed: false }; 

咱們能夠制定一個比回調函數,用來處理對象上的變化:

function observer(changes){ changes.forEach(function(change, i){ console.log('what property changed? ' + change.name); console.log('how did it change? ' + change.type); console.log('whats the current value? ' + change.object[change.name]); console.log(change); // 全部的變化 }); } 

注意:當觀察者回調函數被調用時,被觀察的對象可能已經發生了屢次改變,所以對於每一次變化,新的值(即每次變化之後的值)和當前值(最終的值)並不必定是相同的。

咱們可使用Object.observe()來觀察這些變化,只要將對象做爲第一個參數,而將回調函數做爲第二個參數:

Object.observe(todoModel, observer); 

咱們如今對咱們的Todos的模型對象作一些改變:

todoModel.label = 'Buy some more milk'; 

看看控制檯,咱們如今獲得了一些有用的信息!咱們知道什麼屬性發生了變化,它是怎樣變化的以及新的值是什麼。

再見,髒值檢查!你的墓碑應該被刻上Comic Sans字體。咱們再來改變其餘的屬性。此次改變的是completeBy:

todoModel.completeBy = '01/01/2014'; 

正如咱們所見的,咱們又再一次獲得了關於變化的報告:

很是好。要是咱們如今決定從對象中刪除’completed’屬性會怎麼樣:

delete todoModel.completed; 

正如咱們所見的,返回的變化報告包含了關於刪除的信息。正如咱們所期待的,新的值如今是undefined。那麼,咱們如今知道了你能夠知道屬性何時被添加。何時被刪除。基本上來講,你能夠知道一個對象上的屬性集(’new’,’deleted’,’recongigured’)以及它的原型(proto)的變化。

在任何觀察系統中,老是存在一個方法來中止觀察。在這裏,咱們有Object.unobserve()方法,它的用法和Object.observe()同樣可是能夠像下面同樣被調用:

Object.unobserve(todoModel, observer); 

正以下面所示,在使用該方法以後,任何的變化都再也不做爲一個變化列表記錄返回。

指定感興趣的變化

如今咱們已經瞭解到了咱們如何去獲取一個被觀察對象的變化列表。可是若是咱們僅僅只對一個對象中的某些屬性感興趣該怎麼辦?人人都須要一個垃圾郵件過濾器。Observer能夠經過一個列表指定一些咱們想要看到的變化。咱們須要經過Object.observe()的第三個參數來指定:

Object.observe(obj, callback, opt_acceptList) 

如今咱們來看一個如何使用的例子:

// 就像前面的例子同樣,一個模型能夠是一個簡單的對象 var todoModel = { label: 'Default', completed: false };  // 指定一個回調函數 function observer(changes){ changes.forEach(function(change, i){ console.log(change); }) };  // 指定一個咱們想要觀察的變化類型 Object.observe(todoModel, observer, ['delete']); todoModel.label = 'Buy some milk';  // 注意到變化沒有被報告 

若是咱們刪除了這個標籤,注意到這個類型的變化將會被報告:

delete todoModel.label; 

若是你不指定一個列表,它默認將會報告「固有的」對象變化類型 (」add」, 「update」, 「delete」, 「reconfigure」, 「preventExtensions」 (丟與那些不可擴展的對象是不可觀察的))。

通知

Object.observe()也帶有一些通知。它們並不像是你在手機上看到了通知,而是更加有有用。通知和變異觀察者比較相似。它們發生在微任務的結尾。在瀏覽器的上下文,它幾乎老是位於當前事件處理器的結尾。

這個時間點很是的重要由於基本上來講此時一個工做單元已經結束了,如今觀察者已經開始它們的共走了。這是一個很是好的回合處理模型。

使用一個通知器的工做流程以下所示:

如今咱們經過一個例子來如何經過自定義一個通知器來處理一個對象的屬性被設置或者被獲取的狀況。注意看代碼中的註釋:

// 定義一個簡單的模型 var model = { a: {} };

// 定義一個單獨的變量,咱們即將使用它來做爲咱們的模型中的getter

var _b = 2;

// 在’a’下面定義一個新的屬性’b’,並自定義一個getter和setter

Object.defineProperty(model.a, 'b', { get: function () { return _b; }, set: function (b) {

 // 當'b'在模型中被設置時,注意一個特定類型的變化將會發生  // 這將給你許多關於通知的控制器 Object.getNotifier(this).notify({ type: 'update', name: 'b', oldValue: _b });  // 在值發生變化時將會輸出信息 console.log('set', b); _b = b; } 

});

// 設置咱們的觀察者 function observer(changes) { changes.forEach(function (change, i) { console.log(change); }) }

// 開始觀察model.a Object.observe(model.a, observer);

如今當數據屬性發生變化時(’update’)咱們將會獲得報告。以及任何對象的實現也將會被報告(notifier.notifyChange())。

多年的web平臺開發經驗告訴咱們整合方法是你應該最早嘗試的事情,由於它最容易去實現。可是它存在的問題是以它會創造一個從根本上來看就很未下的處理模型。若是你正在編寫代碼而且更新了一個對象的屬性,你實際上並不想陷入這樣一種困境:更新模型中的屬性會最終致使任意一段代碼去作任意一件事情。當你的函數正好運行到一半時,假設失效並非什麼理想的情況。

若是你是一個觀察者,你並不想當某人正在作某事的時候被調用。你並不像在不連續的狀態下被調用。由於這最終每每會致使更多的錯誤檢查。你應該試着去容忍更多的情形,而且基本上來講它是一個很難去合做的模型。異步是一件更難處理的事情可是最終它會產生更好的模型。

上述問題的解決辦法是變化合成記錄(synthetic change records)。

變化合成記錄

基本上來講,若是你想要存取器或者計算屬性的話,你應該複雜在這些值發生改變時發出通知。這會致使一些額外的工做,可是它是這種機制第一類的特徵,而且這些通知會連同來自餘下的底層數據對象的通知一塊兒被髮布出來。

觀察存取器或者計算屬性的問題能夠經過使用notifier.notify來解決 – 它也是Object.observe()的另一部分。大多數的觀察系統想要某些形式的觀察導出值。有不少方法能夠實現它。Object.observe()並無用「正確的」方式進行判斷。計算屬性應該是存取器,當內部的(私有的)狀態發生改變時它應該發出通知。

再一次聲明,在web中應該有一些庫來幫助咱們進行通知而且幫助咱們更好的實現計算屬性(以及減小模板的使用)。

咱們在這裏會假設一個例子,這個例子中有一個circle類。在這裏,咱們有一個citcle,它有一個radius屬性。在這裏的情形中,radius是一個存取器,而且當它的值發生變化時它實際上會去通知本身值已經發生變化了。這些通知將會連同其餘變化被傳遞到這個對象或者其餘對象。本質上來講,若是你正在實現一個對象,你必定會想要擁有整合或者計算屬性的對象,或者你想要想出一個策略如何讓它運行。一旦你作了這件事,它將會適應你的整個系統。

看看下面的代碼在開發者工具中是如何運行的:

function Circle(r) { var radius = r; var notifier = Object.getNotifier(this); function notifyAreaAndRadius(radius) { notifier.notify({ type: 'update', name: 'radius', oldValue: radius }) notifier.notify({ type: 'update', name: 'area', oldValue: Math.pow(radius * Math.PI, 2) }); } Object.defineProperty(this, 'radius', { get: function() { return radius; }, set: function(r) { if (radius === r) return; notifyAreaAndRadius(radius); radius = r; } }); Object.defineProperty(this, 'area', { get: function() { return Math.pow(radius, 2) * Math.PI; }, set: function(a) { r = Math.sqrt(a)/Math.PI; notifyAreaAndRadius(radius); radius = r; } }); } function observer(changes){ changes.forEach(function(change, i){ console.log(change); }) } 

存取器屬性

在這裏咱們對於存取器屬性有一個簡短的提示。在前面咱們提到了對於數據屬性來講只有值得變化是可以被觀察到的。而存取器屬性和計算屬性則沒法被觀察到。這是由於JavaScript中的存取器並無真正的值的變化。一個存取器僅僅是一個函數集合。

若是你爲一個存取器屬性賦值,你僅僅只是調用了這個函數,而且在它看來值並無發生變化。它僅僅只是讓一些代碼運行起來。

這裏的問題在於咱們在上面的例子中將存取器屬性賦值爲5.咱們應該可以知道這裏究竟發生了什麼。這其實是一個未解決的問題。這個例子說明了緣由。對任何系統來講知道這究竟意味着什麼是不可能的,由於在這裏能夠運行任意代碼。每當存取器屬性被訪問時,它的值都會發生改變,所以詢問它何時會發生變化並無多大的意義。

使用一個回調函數觀察多個對象

Object.observe()上的另外一個模式是使用單個回調觀察者。這容許咱們使用同一個回調函數堆多個不一樣的對象進行觀察。這個回調函數在「微任務」的結尾將會把全部的變化都傳遞給它所觀察的對象。

大規模的變化

也許你正在編寫一個很是大的應用,而且常常須要處理大規模的變化。此時咱們但願用一種更加緊湊的方式來描述影響不少屬性的語義變化。

Object.observe()使用兩個特定的函數來解決這個問題:notifier.performChange()以及notifier.notify(),咱們在上面已經介紹過這兩個函數了。

咱們能夠從下面的例子中看到咱們如何來描述大規模變化,在這個例子中定義了一個叫作Thingy的對象,其中包含幾個數計算功能(multiply, increment, incrementAndMultiply)。只要其中一個功能被使用,它就會告訴系統一些包含特定變化的事情發生了。

例如:notifier.performChange(‘foo’, performFooChangeFn)

function Thingy(a, b, c) { this.a = a; this.b = b; } Thingy.MULTIPLY = 'multiply'; Thingy.INCREMENT = 'increment'; Thingy.INCREMENT_AND_MULTIPLY = 'incrementAndMultiply'; Thingy.prototype = { increment: function(amount) { var notifier = Object.getNotifier(this);  // 告訴系統一系列事情包含一個特定的變化。例如: // notifier.performChange('foo', performFooChangeFn); // notifier.notify('foo', 'fooChangeRecord'); notifier.performChange(Thingy.INCREMENT, function() { this.a += amount; this.b += amount; }, this); notifier.notify({ object: this, type: Thingy.INCREMENT, incremented: amount }); }, multiply: function(amount) { var notifier = Object.getNotifier(this); notifier.performChange(Thingy.MULTIPLY, function() { this.a *= amount; this.b *= amount; }, this); notifier.notify({ object: this, type: Thingy.MULTIPLY, multiplied: amount }); }, incrementAndMultiply: function(incAmount, multAmount) { var notifier = Object.getNotifier(this); notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() { this.increment(incAmount); this.multiply(multAmount); }, this); notifier.notify({ object: this, type: Thingy.INCREMENT_AND_MULTIPLY, incremented: incAmount, multiplied: multAmount }); } } 

咱們能夠爲咱們的對象定義兩個觀察者: 一個用來捕獲全部的變化,另外一個將只會彙報咱們定義的特定類型的變化 (Thingy.INCREMENT, Thingy.MULTIPLY, Thingy.INCREMENT_AND_MULTIPLY)。

var observer, observer2 = { records: undefined, callbackCount: 0, reset: function() { this.records = undefined; this.callbackCount = 0; }, }; observer.callback = function(r) { console.log(r); observer.records = r; observer.callbackCount++; }; observer2.callback = function(r){ console.log('Observer 2', r); } Thingy.observe = function(thingy, callback) {  // Object.observe(obj, callback, opt_acceptList) Object.observe(thingy, callback, [Thingy.INCREMENT, Thingy.MULTIPLY, Thingy.INCREMENT_AND_MULTIPLY, 'update']); } Thingy.unobserve = function(thingy, callback) { Object.unobserve(thingy); 

咱們如今能夠開始玩弄一下代碼了。咱們先定義一個新的Thingy:

var thingy = new Thingy(2,4); 

對它進行觀察並進行一些變化。有趣的事情發生了!

// 觀察thingy Object.observe(thingy, observer.callback); Thingy.observe(thingy, observer2.callback);  // 把玩一下thing暴露的方法 thingy.increment(3);  // { a: 5, b: 7 } thingy.b++;// { a: 5, b: 8 } thingy.multiply(2);// { a: 10, b: 16 } thingy.a++;// { a: 11, b: 16 } thingy.incrementAndMultiply(2, 2); // { a: 26, b: 36 } 

位於這個「perform function」中的一切東西均可以被看做是「大型變化」進行的工做。接受「大型變化」的觀察者僅僅只會接受「大型變化」的記錄。那些不會接受底層變化的觀察者都來源於「perform function」所作的事。

觀察數組

咱們已經討論瞭如何觀察一個對象,可是應該如何觀察數組呢?

Array.observe()是一個針對自身大型變化的方法 – 例如 – splice,unshift或者任何可以隱式影響數組長度的東西。在內部它使用了Internally it uses notifier.performChange(「splice」,…)。

下面是一個咱們如何觀察一個模型「數組」的例子,當底層數據發生一些變化時,咱們將可以獲得一個變化的列表。

var model = ['Buy some milk', 'Learn to code', 'Wear some plaid']; var count = 0; Array.observe(model, function(changeRecords) { count++; console.log('Array observe', changeRecords, count); }); model[0] = 'Teach Paul Lewis to code'; model[1] = 'Channel your inner Paul Irish'; 

性能

考慮Object.observe()性能的方式是將它想成讀緩存。基本上來講,在如下幾種情形中,一個緩存是最佳選擇(按照重要性排序):

  1. 讀的頻率決定着寫的頻率
  2. 你能夠創造一個緩存,它能夠在讀數據期間將涉及到寫數據的操做進行算法上的優化
  3. 寫數據減慢的時間常數是能夠接受的

Object.observe()是爲上述第一種情形設計的。

髒值檢查須要保留一個你所要觀察數據的副本。這意味着在髒值檢查中你須要一個額外的結構內存開銷。髒值檢查,一個做爲權宜之計的解決方案,同時根本上也是一個脆弱的抽象,它可能會致使應用中一些沒必要要的複雜性。

髒值檢查在任何數據可能發生變化的時候都必需要運行。這很明顯並非一個很是魯棒的方法,而且任何實現髒值檢查的途徑都是有缺陷的(例如,在輪詢中進行檢查可能會形成視覺上的假象以及涉及到代碼的紊亂狀況)。髒值檢查也須要註冊一個全局的觀察者,這極可能會形成內存泄漏,而Object.observe()會避免這一點。

咱們如今來看一些數據。

下面的基準測試容許咱們比較髒值檢查和Object.observe()。圖中比較的數據是Observed-Object-Set-Size 和 Number-Of-Mutations。

總的結果代表:髒值檢查的性能和被觀察的對象成正比,而Object.observe()的性能和咱們所作的改變成正比。

  • 髒值檢查

  • 開啓了Object.observe()的Chrome瀏覽器

爲Object.observe()提供墊片

Object.observe()如今已經能夠在Chrome 36 beta中使用,可是若是咱們想要在其餘瀏覽器中使用它該怎麼辦?Polymer中的Observe-JS是一個針對於那些沒有原生實現Object.observe()瀏覽器的一個墊片,可是它不只僅是做爲墊片,同時也包含了許多有用的語法糖。它提供了一種整合的視角,它可以將全部變化總結起來而且提交一份關於變化的報告。它的好處主要體如今兩點:

  1. 你能夠觀察路徑。這意味着你能夠說,我想要從一個給定的對象中觀察’foo.bar.baz’,只要這個路徑的值發生了改變,你會獲得通知。若是路徑是錯誤的,將會返回undefined。

下面是一個例子:

var obj = { foo: { bar: 'baz' } }; var observer = new PathObserver(obj, 'foo.bar'); observer.open(function(newValue, oldValue) {  // 針對於 obj.foo.bar 已經改變的值進行響應 }); 
  1. 它可以告訴你數組的拼接。數組拼接基本上來講是你爲了將舊版本數組轉換爲新版本數組是須要進行了最基本的拼接操做。這是一種轉換的類型或者是這個數組的不一樣視圖。它是你想要將數組從舊狀態變爲新狀態時須要進行的最基本的工做。

下面是一個例子

var arr = [0, 1, 2, 4]; var observer = new ArrayObserver(arr); observer.open(function(splices) {  // 響應arr元素的變化 splices.forEach(function(splice) { splice.index; // 變化發生的位置 splice.removed; // 一個表明被移除的元素的序列值數組 splice.addedCount; // 被插入元素的個數 }); }); 

框架和Object.observe()

正如上面所提到的,使用Object.observe()可以給予框架和庫中關於數據綁定的性能巨大的提高。

來自Ember的Yehuda Katz和Erik Bryn已經肯定將會在Ember最近的修改版本中添加對Object.observe()的支持。來自Angular的Misko Hervy寫了一份關於Angular 2.0的設計文檔,其中的內容關於改善變化探測(change detection)。在未來,當Object.observe()在Chrome穩定版中出現時,Angular會使用Object.observe()來實現變化探測的功能,在此以前它們會選擇使用Watchtower.js – Angular本身的變化探測的實現方式。實在是太使人激動了。

總結

Object.observe()是一個添加到web平臺上很是強大的特性,你如今就能夠開始使用它。

咱們但願這項特徵可以及時的登錄到更多的瀏覽器中,它可以容許JavaScript框架從本地對象觀察的能力中得到更多性能上的提高。Chrome 36 beta及其以上的版本都能使用這項特性,在將來Opera發佈的版本中這項特性也會獲得支持。

如今就和JavaScript框架做者談談Object.observe()如何可以提升他們框架中數據綁定的性能。將來還有更多讓人激動的時刻。

參考材料


本文譯自Data-binding Revolutions with Object.observe(),原文地址http://www.html5rocks.com/en/tutorials/es7/observe/#toc-notifications

若是你以爲本文對你有幫助,請爲我提供贊助 https://me.alipay.com/jabez128

 

http://www.html-js.com/article/A-day-to-learn-Objectobserve-JavaScript-binding-data-change

相關文章
相關標籤/搜索