object.observe,又稱O.O,是ecmascript 7的一部分,是一個要添加到JavaScript中的功能,以在瀏覽器中本地支持對象更改檢測。儘管ES7尚未完成,但此功能已經在基於眨眼的瀏覽器(Chrome和Opera)中支持。
>。
因為object.observe將由瀏覽器本地支持,並且它直接在對像上起作用而無需創建周圍的任何包裝器,因此API既易於使用又易於使用。如果Object.Observe由瀏覽器支持,則可以實現雙向綁定而無需外部庫。這並不意味著一旦實現了O.O,所有現有的雙向綁定庫將無用。我們仍然需要它們在使用O.O.檢測更改後有效地更新UI。此外,如果並非全部針對的瀏覽器支持O.O.
observe()方法是一種在對像上定義的異步靜態方法。它可用於尋找對象的更改,並且接受三個參數:
一個要觀察的對象
>>如果您在控制台上看到輸出,則會發現所有三個更改均被檢測到並記錄。以下屏幕截圖顯示了摘要產生的結果:
<span>var person = { </span> <span>name: 'Ravi', </span> <span>country: 'India', </span> <span>gender: 'Male' </span><span>}; </span> <span>function observeCallback(changes){ </span> <span>console.log(changes); </span><span>}; </span> <span>Object.observe(person, observeCallback); </span> person<span>.name = 'Rama'; // Updating value </span>person<span>.occupation = 'writer'; // Adding a new property </span><span>delete person.gender; // Deleting a property</span>
o.o不同步運行,它將所有更改都發生了,並在調用時將它們傳遞給回調。因此,在這裡,我們收到了對對像上應用的三個更改的三個條目。如您所見,每個條目都由屬性的名稱更改,舊值,更改的類型以及具有新值的對象本身。
>下面報告了上一個代碼的實時演示(請記住要打開控制台以查看結果):請參閱codepen上的sitepoint(@sitepoint)的筆emkveb。 在我們的代碼中,我們沒有指定要查找的更改的類型,因此它觀察到添加,更新和刪除。可以使用觀察方法的第三個參數來控制這:
<span>var person = { </span> <span>name: 'Ravi', </span> <span>country: 'India', </span> <span>gender: 'Male' </span><span>}; </span> <span>function observeCallback(changes){ </span> <span>console.log(changes); </span><span>}; </span> <span>Object.observe(person, observeCallback); </span> person<span>.name = 'Rama'; // Updating value </span>person<span>.occupation = 'writer'; // Adding a new property </span><span>delete person.gender; // Deleting a property</span>
observe()方法能夠檢測對添加到對象的直接屬性上所做的更改。它無法檢測使用Geters和setter創建的屬性的更改。由於這些屬性的行為由作者控制,因此變更檢測也必須由作者擁有。要解決此問題,我們需要使用通知器(通過object.getNotifier()獲得)來通知屬性上所做的更改。
>考慮以下片段:
<span>Object.observe(person, observeCallback, ['add', 'update']);</span>
toodype是具有兩個屬性的構造函數。除此之外,還使用object.defineproperty添加了阻塞。在我們的示例中,為此屬性定義的設置器很簡單。在典型的業務應用程序中,它可能執行一些驗證,並且如果驗證失敗,則可能無法設置值。但是,我想讓事情變得簡單。
最後注意,您可以看到在我們的示例中,只有在有更新時發送通知。
對屬性進行的更改會在Chrome開發人員工具中產生以下結果:
請參閱codepen上的sitepoint(@sitepoint)的筆npzgoo。
觀察多個變化
有時,在以某種方式修改兩個或多個屬性後,我們可能有一個計算要運行。儘管我們可以使用通知器單獨通知這兩個更改,但是最好發送帶有自定義類型名稱的單個通知,以表明兩個值都已修改。這可以使用notifier.performchange()方法完成。此方法接受三個參數:>自定義類型的名稱
執行更改的回調函數>一旦執行了pertermchange回調的邏輯,將通過傳遞的自定義更改類型通知更改。 Observe默認情況下不會觀察到這種類型。我們需要明確要求O.O觀察自定義類型的更改。以下片段在托多對像上顯示了一個修改的o.o,以觀察自定義類型的更改以及添加和更新類型: >上面的摘要將“封鎖”值設置為true之前,然後將其設置為true。因此,它發送了帶有自定義更改類型的通知。以下屏幕截圖顯示了由自定義類型返回的更改對象的詳細信息:
觀察數組
請參閱codepen上的sitepoint(@sitepoint)的筆gggezq。
結論 為什麼對object.observe棄用了? 對象。它無法觀察到功能中所做的更改,也無法跟踪對象原型的更改。此外,發現它在性能方面效率低下,因為它需要大量資源來跟踪大對象的變化。貶值也受到ES6中新功能(例如代理和反思)的引入的影響,這些特徵提供了更有效的方法來觀察和反應對象的變化。 > es6 proxies如何作為object.observe的替代方案? > ES6代理提供了一種自定義對像上基本操作的行為的方法。使用兩個參數創建代理:目標對象和處理程序對象。處理程序對象為目標對象的各種操作定義了“陷阱”。執行這些操作後,觸發處理程序中的相應陷阱,從而可以執行自定義行為。這使得代理成為觀察對像變化和反應的強大工具。 我仍然可以在項目中使用object。仍然使用對象。在您的項目中,它是強烈灰心的。 Obser.Observe已被棄用並從JavaScript標準中刪除,這意味著它不再維護,並且可能不受所有瀏覽器的支持。使用折衷的功能可能會導致項目中的兼容性問題和其他問題。建議使用諸如ES6代理或庫之類的替代方案,例如mobx或vue.js. ES6代理通常比Object.Observe更有效,尤其是在處理大型對象時。但是,像任何功能一樣,應明智地使用它們。為應用程序中的每個對象創建代理都會導致性能問題。最好僅在必要時使用代理,並保持處理程序盡可能輕巧。 如何處理MOBX或VUE.JS之類的庫處理對象觀察? > JavaScript中對象觀察的未來是什麼? JavaScript可能會因語言的持續發展以及庫和框架的發展而塑造。 ES6代理和反思之類的功能為觀察和反應對象的變化提供了強大的工具,MOBX和VUE.JS之類的庫以這些工具為基礎,以提供高級API來進行對象觀察。隨著語言和生態系統的繼續發展,我們可以期望看到更有效,更靈活的方法來觀察對象的變化。<span>var person = {
</span> <span>name: 'Ravi',
</span> <span>country: 'India',
</span> <span>gender: 'Male'
</span><span>};
</span>
<span>function observeCallback(changes){
</span> <span>console.log(changes);
</span><span>};
</span>
<span>Object.observe(person, observeCallback);
</span>
person<span>.name = 'Rama'; // Updating value
</span>person<span>.occupation = 'writer'; // Adding a new property
</span><span>delete person.gender; // Deleting a property</span>
>下面報告了此示例的實時演示(請記住要打開控制台以查看結果):
觀察數組類似於觀察對象。唯一的區別是觀察者函數必須使用array.observe而不是object.observe註冊。以下片段證明了這一點:
<span>Object.observe(person, observeCallback, ['add', 'update']);</span>
>
<span>function <span>TodoType</span>() {
</span> <span>this.item = '';
</span> <span>this.maxTime = '';
</span>
<span>var blocked = false;
</span>
<span>Object.defineProperty(this, 'blocked', {
</span> <span>get:function(){
</span> <span>return blocked;
</span> <span>},
</span> <span>set: function(value){
</span> <span>Object.getNotifier(this).notify({
</span> <span>type: 'update',
</span> <span>name: 'blocked',
</span> <span>oldValue: blocked
</span> <span>});
</span> blocked <span>= value;
</span> <span>}
</span> <span>});
</span><span>}
</span>
<span>var todo = new TodoType();
</span>
todo<span>.item = 'Get milk';
</span>todo<span>.maxTime = '1PM';
</span>
<span>console.log(todo.blocked);
</span>
<span>Object.observe(todo, function(changes){
</span> <span>console.log(changes);
</span><span>}, ['add', 'update']);
</span>
todo<span>.item = 'Go to office';
</span>todo<span>.blocked = true;</span>
>
客戶端雙向綁定周圍的未來將通過瀏覽器的出色添加而更加明亮。讓我們期待其他瀏覽器儘早趕上!
經常詢問的問題(常見問題解答)。
> aboce.observe的替代方法是什麼?最受歡迎的選擇之一是使用ES6代理。代理允許您為對象的基本操作定義自定義行為,例如屬性查找,分配,枚舉,功能調用等。另一種選擇是使用庫(例如mobx或vue.js),它們提供了自己的機制來觀察對象的變化。
>使用ES6代理而不是對象。它們提供了一種更靈活,更有力的方法來觀察和對物體變化的反應。使用代理,您可以為廣泛的操作定義自定義行為,而不僅僅是對屬性的變化。代理也比Object.Observe更好,尤其是在處理大型對象時。此外,代理是ES6標準的一部分,這意味著它們得到了所有現代瀏覽器的支持。
>我如何從對象遷移。代理涉及替換對象。用代理對象訪問呼叫。您沒有觀察到對象屬性的更改,而是為要在代理的處理程序對像中觀察到的操作定義陷阱。這可能涉及您的代碼進行一些重構,但它提供了一種更加靈活,更有效的方法來觀察對象的變化。
使用ES6代理的性能影響是什麼?
使用ES6 Proxies是否存在任何限製或問題?他們確實有一些局限性。例如,它們不能用於觀察對數組長度屬性的更改。同樣,代理並不能提供觀察對象原型更改的方法。但是,通常可以使用ES6的其他功能來解決這些局限性,例如Reffle。
MOBX或VUE等庫.js提供了自己的機制來觀察對象的變化。例如,MOBX使用可觀察的屬性和計算值來跟踪變化,而VUE.JS使用反應性數據模型。這些庫提供了用於對象觀察的高級API,使其比原始的ES6代理更易於使用。
以上是對像簡介的詳細內容。更多資訊請關注PHP中文網其他相關文章!