What can the JavaScript prototype system do beyond mimicking a classical class system?

javascript, prototype, prototype-programming

Solution

The prototype system offers a captivating model of metaprogramming, by implementing inheritance via standard objects. Of course, this is mostly used to express the established and simple concept of classes of instances, but without classes as language-level immutable structures that need specific syntax to create them. By using plain objects, all you can do to objects (and you can do everything) you can now do to "classes" - this is the flexibility you talk of.

This flexibility is then used a lot to extend and alter classes programmatically, using only the given object-mutation capabilities of JavaScript:

- mixins and traits for multiple inheritance

- prototypes can be modified after objects that inherit from them have been instantiated

- higher-order functions and method decorators can be used easily in the creation of prototypes

Of course, the prototype model itself is more powerful than to just implement classes. These features are used rather seldom, as the class concept is very useful and widespread, so the actual powers of prototype inheritance are not well-known (and not well-optimised in JS engines :-/)

switching out prototypes of existing objects can be used to alter their behaviour dramatically. (full support coming with ES6 `Reflect.setPrototypeOf`)

a few software engineering patterns can be implemented directly with objects. Examples are the flyweight pattern with properties, a chain of responsibilities including dynamic chains, oh, and of course the prototype pattern.

A good example for the last one would be option objects with defaults. Everyone creates them using

  var myOptions = extend({}, defaultOptions, optionArgument);

but a more dynamic approach would be to use

  var myOptions = extend(Object.create(defaultOptions), optionArgument);

Problem

The prototype system looks much more flexible than the traditional class system, but people seem to feel content with the so-called "best practices", which mimic the traditional class system: ``` function foo() { // define instance properties here } foo.prototype.method = //define instance method here new foo() ``` There must be other things that a prototypal system can do with all the flexibility. Are there uses for a prototypal system outside of mimicking classes? What kinds of things can prototypes do which classes cannot, or are there none?

Original source

Related problems