---
title: Object.observe is dead, long live ES6 Proxies
description: ES6 Proxies solve one of the core challenges of JavaScript framework authors.
image: https://www.bitovi.com/hubfs/donjs-banner.jpg
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting)
- ![Project Management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project Management](https://www.bitovi.com/services/agile-project-management-consulting)
- ![Product Design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product Design](https://www.bitovi.com/services/product-design-consulting)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting)
- [Design systems](https://www.bitovi.com/services/axure-figma-migration)
- [React](https://www.bitovi.com/services/frontend/react-consulting)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about delivering products and solving problems.
  
  ](https://www.bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships)
- [![Academy](https://www.bitovi.com/hubfs/icon%20-%20academy%20(4).svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse or contribute to our community
  
  ](https://www.bitovi.com/open-source)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

 February 2, 2016

# Object.observe is dead, long live ES6 Proxies

 ES6 Proxies solve one of the core challenges of JavaScript framework authors.

![Justin Meyer](https://www.bitovi.com/hubfs/justin.jpeg)

 Justin Meyer

Share:

[![Twitter](https://www.bitovi.com/hubfs/limbo-generated/_astro/twitter-white.os3xLc3C_Z2nW4or.svg) ](https://twitter.com/intent/tweet?text=) [![Reddit](https://www.bitovi.com/hubfs/limbo-generated/imgs/icons/reddit.png) ](http://reddit.com/submit?url=)

Observables and "computed" values are something that every modern framework provides in some fashion. Frameworks that have explicit observables and computed values (Ember, Knockout, [CanJS](https://canjs.com/), etc) can provide high performance updates and, in my opinion, a more natural development experience.

```
var fullName = can.compute(function(){
  return person.attr("first")+" "+person.attr("last")
});
```

However, frameworks like Angular and React, that can use plain JS objects, lend themselves to being more popular, but accomplish computed values with sub-optimal dirty checking or diffing.

```
$scope.fullName = function() {
  return $scope.firstName + " " + $scope.lastName;
}
```

[Object.observe](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe) was viewed as a solution for observables but was recently [retracted](https://esdiscuss.org/topic/an-update-on-object-observe).

I was happy to see this because `Object.observe` did not help the computed value problem. ES6 already has a data structure that solves observables, computed values, and a wide variety of other framework/library problems - [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy).

In the remainder of this article, I'll explain how proxies support explicit observables, computed values, and a more natural DOT operator (`.`) based syntax. Essentially, Proxies make the best of both worlds possible. I'll conclude by politely asking browser vendors, especially mobile browser vendors, to add this feature.

## Frameworks with explicit observables

Ember, Knockout, [CanJS](https://canjs.com/), and many other frameworks have explicit observables and computed values or properties. For example, in [CanJS](https://canjs.com/), the following creates a `fullName` compute that updates whenever any of its source observables change:

```
var person = new can.Map({first: "Justin", last: "Meyer"});

var fullName = can.compute(function(){
  return person.attr("first")+" "+person.attr("last")
});

fullName.bind("change", function(ev, newVal, oldVal){
  // newVal => "Vyacheslav Egorov"
  // oldVal => "Justin Meyer"
})

// causes change event above
person.attr({first: "Vyacheslav", last: "Egorov"});
```

This works by having `.attr(prop)` tell the computed system that some observable value is being read. The computed system listens for those changes. Computes are like event streams. They are slightly less powerful, but much easier to use.

Knockout is similar:

```
function AppViewModel() {
    this.firstName = ko.observable('Bob');
    this.lastName = ko.observable('Smith');
    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
}
```

The developer doesn't have to explicitly tell the compute what is being read. This information is inferred as the function is run. This allows a great deal of flexibility. For instance, plain JavaScript functions can be composed:

```
var person = new can.Map({
  first: "Justin", 
  last: "Meyer"
});
var hobbiesList = new can.List([
  "basketball",
  "programming"
]);

var fullName = function(){
  return person.attr("first")+" "+person.attr("last")
};

var hobbies = function(){
  return hobbiesList.join(",")
}

var info = can.compute(function(){
  return fullName()+" likes "+hobbies();
});
```

Direct observables and computes allow frameworks to only update exactly what is needed without having to **dirty check** or **signal an update and diff**.

**Note: In an article that will be released next week, we will show how observables can be used to update the DOM algorithmically faster than dirty checking (in logarithmic instead of linear time).**

## Frameworks without explicit observables

Frameworks without explicit observables, like Angular and React are more popular. Users like using the `DOT(.)` operator. But it comes at a cost.

### Angular

In Angular, you can do something like:

```
$scope.fullName = function() {
  return $scope.firstName + " " + $scope.lastName;
}
```

This will use dirty checking to continuously read the value of `fullName`. You can do something like:

```
var fullName = function() {
  $scope.fullName = $scope.firstName + " " +
                    $scope.lastName;
}
$scope.$watch('firstName', fullName, true);
$scope.$watch('lastName', fullName, true);
```

but you have to write out the values you care about twice:

- Once to compose the value (`$scope.firstName`).
- Twice to bind the value (`$watch('firstName',...`).

Gross!

### React

With React/JSX, you might do something like:

```
render () {
  var fullName = this.props.firstName + " " + 
                 this.props.lastName;
  return (
      <div>
        <h2>{fullName}</h2>
      </div>
    );
}
```

 

[![Free Javascript checklist. Keep track of your project and ensure high quality.](https://no-cache.hubspot.com/cta/default/2171535/13cba1e8-330a-4523-b9ee-42256e7c02cb.png)](https://cta-redirect.hubspot.com/cta/redirect/2171535/13cba1e8-330a-4523-b9ee-42256e7c02cb)

 Instead of dirty checking, React requires a call to `setState`. This is similar in style to updating an observable's value (like CanJS's `.attr`). However, `setState` doesn't produce events. Instead, React re-renders the template to a virtual DOM and calculates DOM updates by taking a difference of the virtual DOM and the actual DOM. The re-render of the entire template and diff are each `O(n)` at best. With observables, there's no re-render and diff necessary.

 

## Enter proxies

Proxies will allow frameworks to provide explicit observables with an `Object`-like API that uses the DOT (.) operator. For example:

```
var person = can.observable();
person.first = "Justin";
person.last = "Meyer";

var fullName = can.compute(function(){
  return person.first+" "+person.last
});

// causes change event above
person.first = "Vyacheslav";
person.last = "Egorov";
```

I showed it this way because users do not want to define all properties up front, making `Object.defineProperty` and getter/setters an unviable option. I made a version of this that works in browsers that support `Proxy` [here](https://github.com/canjs/can-observe).

With Proxies, Angular could remove the need for dirty checking (assuming $scope is a proxy). React's `render` function could know when to call itself, removing the meatball in the middle of many flux apps (I can elaborate on this more in the comments).

With Proxies, Knockout, [CanJS](https://canjs.com/), and Ember users could use the familiar DOT(.) operator.

## Can I use it?

Search for "Proxy" in [this compatibility table](https://kangax.github.io/compat-table/es6/) to see the current state of Proxy support. Desktop support is very promising. Proxies have been in Firefox for a very long time. They are also in Edge and in Chrome Canary. Great job browser teams!

The hold out has been Safari and mobile browsers.

If you're a Safari or mobile browser developer, please consider prioritizing proxies. Adding proxies might have as big of an impact as any other ES6 feature to an average developer. Average developers wouldn't use it directly, but it would be an invaluable tool to library and framework authors.

---

*Also published on [Medium](https://medium.com/bitovi-design-and-development/object-observe-is-dead-long-live-es6-proxies-c3f25454342#.fe4fo4osi).*

[![Tag for open source](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) open source ](https://www.bitovi.com/blog/topic/open-source)[![Tag for development](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) development ](https://www.bitovi.com/blog/topic/development)

 Previous Post

![canjs-background-blue-1.gif](https://www.bitovi.com/hs-fs/hubfs/canjs-background-blue-1.gif?height=117&name=canjs-background-blue-1.gif) [ CanJS 2.3 Release ](https://www.bitovi.com/blog/canjs-2-3-release)

  

 Next Post

![background-change-propagation-darker1.jpg](https://www.bitovi.com/hs-fs/hubfs/background-change-propagation-darker1.jpg?height=117&name=background-change-propagation-darker1.jpg) [ Be proactive, not reactive - Faster DOM updates via change propagation ](https://www.bitovi.com/blog/change-propagation)

```json
{
  "@context" : "http://schema.org",
  "@type" : "Organization",
  "address" : {
    "@type" : "PostalAddress",
    "addressCountry" : "United States",
    "addressLocality" : "Libertyville",
    "addressRegion" : "IL",
    "postalCode" : "60048",
    "streetAddress" : "1134 Pine Tree Lane "
  },
  "alternateName" : "Bitovi",
  "areaServed" : {
    "@type" : "GeoCircle",
    "geoMidpoint" : {
      "@type" : "GeoCoordinates",
      "latitude" : "41.8781",
      "longitude" : "87.6298"
    },
    "geoRadius" : "5000 km"
  },
  "description" : "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
  "email" : "contact@bitovi.com",
  "image" : "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
  "logo" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
  "mainEntityOfPage" : {
    "@id" : "https://www.bitovi.com/blog/long-live-es6-proxies",
    "@type" : "WebPage",
    "description" : "ES6 Proxies solve one of the core challenges of JavaScript framework authors."
  },
  "naics" : "541511",
  "name" : "Bitovi Web App Consulting",
  "sameAs" : [ "https://www.facebook.com/BitoviLLC/", "https://twitter.com/bitovi", "https://www.linkedin.com/company/bitovi" ],
  "telephone" : "312-620-0386",
  "url" : "http://bitovi.com"
}
```

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Justin Meyer"
  },
  "dateModified" : "December 5, 2018, 1:29:11 AM",
  "datePublished" : "2016-02-02 18:30:50",
  "description" : "ES6 Proxies solve one of the core challenges of JavaScript framework authors.",
  "headline" : "Object.observe is dead, long live ES6 Proxies",
  "image" : {
    "@type" : "ImageObject",
    "url" : "http://cdn2.hubspot.net/hubfs/2171535/donjs-banner.jpg"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg"
    },
    "name" : "Bitovi"
  }
}
```