Like model classes in many other JavaScript MVC frameworks, Ember.Object
uses
get()
/set()
-based property accessor functions rather than native JavaScript
properties:
1 2 3 4 5 |
|
Of course, Ember provides computed properties and property bindings, features
that plain JavaScript properties don’t support. Fortunately, ECMAScript 5 includes
property descriptors, and in particular, the
Object.defineProperty()
method. Object.defineProperty
allows you to specify a function to serve as a
getter for the property (for example, to implement a computed property) and a
corresponding function to serve as a setter (which can be used to implement
properties that notify their observers when they change). So why doesn’t Ember
use property descriptors to provide more natural, less intrusive object properties?
Browser compatibility is only part of the answer. Browser support for property descriptors is actually reasonably decent: present on Firefox, Chrome, Safari, and Opera (naturally), and IE >= 9. For applications that can afford to drop IE 8 support, particularly mobile apps, property descriptor-based model objects would work great.
The other part of the answer is that Ember provides a feature that goes beyond what
property descriptors can support: unknown properties. This is a feature akin to
Ruby’s method_missing
, where you can define a handler that’s called upon access
to a property you haven’t explicitly defined:
1 2 3 4 5 6 7 |
|
Property descriptors do not allow you to define a function that’s called when a
previously undefined property is accessed or assigned. Accesses of undefined properties
simply produce undefined
, and without a previously installed setter function the
object has no way of detecting assignment to a previously undefined property,
which it needs to be able to do in order to notify observers of the change. So
Ember needs something more than property descriptors in order to support
unknown properties.
Good news: that “something more” is on the horizon, in the form of
object proxies, a
language feature slated for ECMAScript Harmony, the next release of the JavaScript
standard. Object proxies allow you to create a virtualized object that wraps a
given target object. The key feature for Ember is that get
and set
are part
of the proxy API, permitting the wrapper to intercept and handle all property
accesses and assignments, even for unknown properties.
Bad news: it will be awhile before support for object proxies is widespread. Currently,
support is limited to Firefox
and Chrome
(after enabling “Experimental JavaScript” in chrome://flags
),
both of which actually support an older, slightly different proxy specification.
Thanks to Tom Dale for answering this question for me. Any inaccuracies in the above are my own.