Rispondere al cambiamento con Object.observe

Alex Danilo

Molti framework JavaScript che utilizzano MVC o MDV devono rispondere alle modifiche agli oggetti che modellano lo stato all'interno di un'applicazione web. Questa funzionalità è una parte fondamentale di un modello di associazione dati.

Esistono diversi modi per monitorare gli oggetti JavaScript e le proprietà DOM al fine di attivare un qualche tipo di azione, ma la maggior parte delle tecniche non è ideale per vari motivi, come le prestazioni e così via.

Per migliorare le prestazioni delle applicazioni web, è stato proposto al TC39 un nuovo metodo chiamato Object.observe(), l'organismo degli standard che supervisiona lo sviluppo di ECMAScript (JavaScript).

Object.observe() consente di aggiungere un listener a qualsiasi oggetto JavaScript che viene chiamato ogni volta che l'oggetto o le sue proprietà cambiano.

Puoi provarla subito nella versione 25 di Chrome Canary.

Per sperimentare questa funzionalità, devi attivare il flag Attiva JavaScript sperimentale in Chrome Canary e riavviare il browser. Il flag è disponibile in "about:flags", come mostrato nell'immagine seguente:

I flag di Chrome.

Ecco un semplice esempio di come impostare un osservatore su un oggetto:

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

Quando l'oggetto "beingWatched" viene modificato, attiva la funzione di callback "somethingChanged", che riceve un array di modifiche applicate all'oggetto.

Il motore JavaScript è quindi libero di eseguire il buffering di una serie di modifiche e di passarle tutte in un'unica chiamata alla funzione di callback. Ciò consente di ottimizzare i callback in modo che il codice possa eseguire molte manipolazioni di JavaScript, ma elabori solo alcuni callback raggruppando gli aggiornamenti.

La funzione di callback viene attivata ogni volta che una proprietà viene aggiunta, modificata, eliminata o riconfigurata.

Un'altra cosa interessante quando si osservano gli array è che, se a un array sono state apportate diverse modifiche, è possibile utilizzare una libreria di supporto Riepilogo modifiche per creare un insieme di modifiche minime, in modo che il codice JavaScript lato client non debba analizzare manualmente l'array per controllare ogni elemento.

Puoi eseguire l'iterazione di ogni modifica molto facilmente, eseguendo un'operazione simile alla seguente nella funzione di callback "somethingChanged":

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

La proprietà type identifica cosa è successo all'oggetto. Nel codice seguente sono riportati alcuni esempi di proprietà che vengono impostate e del tipo associato.

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

L'aspetto fantastico di questa tecnica è che tutte le funzionalità di monitoraggio si trovano all'interno del motore JavaScript, il che consente al browser di ottimizzarla bene e di liberare JavaScript per implementare funzionalità sfruttando questa funzionalità.

Un'altra funzionalità molto utile per lo sviluppo è la possibilità di utilizzare Object.observe() per attivare il debugger ogni volta che un oggetto viene modificato. A tal fine, devi utilizzare un codice simile all'esempio riportato di seguito.

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

Ecco un'ottima introduzione video su Object.observe() che spiega in dettaglio.

È disponibile anche un bel testo descrittivo e un esempio funzionante qui.

L'organismo degli standard TC39 vorrebbe ricevere un feedback su questa funzionalità, perciò provala e facci sapere cosa ne pensi.