Extending the JavaScript Object Model

December 17, 2010

in JavaScript,Web Standards

At the core of the JavaScript language is its “object model”. An object model defines the object abstraction of an language.  It tells users how to think about objects in a language — how are objects composed and what they can do.  It also tells language implementers what they must manifest as an object to users of the language.

JavaScript has a very simple object model.  An object is essentially just a set of key/value pairs called properties where the keys are string values.  In addition each object has an “inherits properties from” relationship with another object.  Some users and some implementers actually think in terms of a slightly more complex object model where in addition to string key/value pair properties an object may have indexed properties where the keys are integers.  However, that elaboration isn’t really essential to the understanding of the JavaScript object model because such integer keys can be understood in terms of their string representations.

Developers of JavaScript implementations spend a lot of time designing ways to optimizing their implementation of the JavaScript object model.   The simplicity of the object model allows for a very simple implementation, but such simple implementations will typically have very poor performance.  In order to have excellent performance implementers need to develop mechanisms that optimize the implementation while still maintaining the JavaScript programmer’s perception of it simple basic object model.  These mechanisms typically include complex caching and analysis techniques that try to transparently eliminate most of the dynamic overhead of the object model.

The object model defines many programers’ understanding of JavaScript and it plays a central role  in the design of JavaScript implementations. For these reasons, any major proposal to extend JavaScript needs to be critically examined for its impact upon the existing JavaScript object mode.  If the extension requires a major change to the object model, it may be difficult for programers to understand and use.  For implementers, even seemly simple object model changes may require significant redesign of existing optimization mechanisms and the invention of new techniques.

When possible, it is probably better to try to support a new requirement by extending some existing characteristic of the object model rather than by adding something that is totally new and unrelated to anything in the current object model.  Such extensions are more likely to be understood by programmers and to most easily fit into existing implementation designs.  For example, ECMAScript 5 added the concept of accessor (getter/setter) properties to the object model.  It did this by extending what can constitute the “value” part of a property.  Similarly, the Private Names proposal for ECMAScript Harmony extends what can constitute the “key” part of a property.  Both proposal are similar in that they building upon preexisting object property characteristics.  They don’t add major new concepts to the object model that are not directly related to properties.

There may be future situations that justify the conceptual and implementation cost of extending the JavaScript object model with concepts that are not related to properties.  However, the likely benefit of such an extension needs to be very large. For that reason, I want to propose a principle that any designer of a JavaScript extension should use as a starting point.  Try to work within the basic key/value pair property and prototype inheritance design of the current JavaScript model. Only introduce new non-property concepts into the object model as a last resort.


Previous post:

Next post: