Death of Object.observe()

By on November 6, 2015 9:47 am


Adam Klien, software engineer at Google, announced on ESDiscuss that they were withdrawing the proposal to implement Object.observe and plan to remove it from V8 by the end of the year.

While I was never sold on the approach of this API, I assumed long ago it was the API that would be used for data binding to plain old JavaScript objects. I am also surprised because I was discussing the state of Web Components with a member of TC39 just a few weeks ago. While I listed all the parts of Web Components that are in V8/Blink but not elsewhere, including Object.observe, they assured me the other browsers would eventually implement the rest of Web Components. I also missed that Polymer 1.0 abandoned Object.observe.

At SitePen and in the Dojo Community, we did struggle with the limits of the API. It was essentially too fine grained to be of practical use and required a decent amount of higher order functionality in non-native code to actually deliver what was a generally consumable API. We had already delivered a shim for Dojo 2 but clearly we will need to rethink our approach.

The announcement mentions that React/Flux, which doesn’t use object mutability as a way of tracking change, has become popular. I believe that is where a lot of our thinking has been headed for Dojo 2 as well. Bidirectional data binding against POJOs might make sense if you are building from the ground up, thinking “what do I need?”. However, when you take a step back from things, you realize that it’s difficult to maintain code and you are left wondering why your application behaves unpredictably. For example, if you have several widgets acting on the same state and then reflecting that state in their interface, you may end up in an infinite loop. Because of a system like Flux, where changes only flow in one direction and pass through a dispatcher, it is much easier to manage conflicting state changes. Also, it promotes encapsulation. As a software engineer, you only have to understand the part of the code you are working on, versus a complex mesh of run-time dependencies.

Also, if you look at Proxy, which made it as part of ES6, there is little functional capability that Object.observe delivered that could not be created with Proxy. In addition, you could solve significantly more problems with Proxy if required. Basically, a Proxy is a native implementation that lets you inject code between the consumer and the target object. It can allow you to do anything from controlling, changing, enforcing, modifying, or aggregating state–not just observe it.

I feel that if a Stage 2 proposal that was implemented in a prominent run-time engine that powers Chrome, Node.js and Opera does get pulled, it is a clear indication to the rest of us that we need to be a bit more careful about investing time and effort in adopting something that might not make it as a standard. It also continues to give credence to the situation that not every bright idea should land in production and that a lot of these ideas need more hardening. Hopefully it is a sign that TC39 is working, but a more cynical view is that TC39 might not take on big problems to solve, because it requires too much politicking and compromise. For example, instead of a native data binding solution, we get the exponentiation operator. I don’t want to take away from those who worked to deliver the exponentiation operator, but it was a relatively “small” problem to solve and it still took a lot of politicking and compromise.

In the end, I get the feeling that we, the framework and toolkit builders, are left on our own to solve the problem of data binding. If anything, it reinforces to me that sometimes low-level solutions don’t always solve the macro problem of building Web Applications. Also, I think it means we should take a stronger look at unidirectional flow of state for Dojo 2.