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?
Prototypes allow you to easily define methods to all instances of a particular object. The beauty is that the method is applied to the prototype, so it is only stored in the memory once, but every instance of the object has access to it.
There is a clear reason why you should use prototypes when creating classes in JavaScript. They use less memory. When a method is defined using this. methodName a new copy is created every time a new object is instantiated.
In prototypical inheritance, prototypes are object instances to which child instances delegate undefined properties. In contrast, classes in classical inheritance are type definitions, from which child classes inherit methods and properties during instantiation.
The prototype is an object that is associated with every functions and objects by default in JavaScript, where function's prototype property is accessible and modifiable and object's prototype property (aka attribute) is not visible. Every function includes prototype object by default.
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:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With