Closed pluma closed 11 years ago
No. .methods()
and .state()
both represent two different kinds of prototypes. .methods()
are for the delegate prototype, while state is for the exemplar prototype (clone source). It has not been known as a prototype in the past, but .enclose()
functions can also be seen as prototypes for initializer functions: That is, functions that are applied to every new instance of an object.
They have specific names to clarify the best use-case for each.
After all you can pass in other things than methods (e.g. getters, setters and values) and they will behave just like they would on a prototype.
Getters and setters are methods, and using values on a delegate prototype is an anti-pattern, for two reasons:
Stampit doesn't have class inheritance, but prototypal inheritance is not just a form of inheritance, it is a superior form of inheritance. For more on these topics, see the blog post, Fluent JavaScript: Three Different Kinds of Prototypal OO, and the corresponding talk, Classical Inheritance is Obsolete: How to Think in Prototypal OO.
Thanks for your response.
I'm aware of your articles and talk. I did not mean to imply stampit had class inheritance, I was just noting that it did not have delegating inheritance, i.e. if you try to derive one stamp from another, the result will be a concatenation of both stamps' prototypes, so changes to either stamp will not be reflected on the "child" stamp.
For clarification: I am using the term "prototype" to refer to what is passed to Object.create
, i.e. the resulting object's [[Prototype]]
(or in your explanation, the "delegate prototype"). I'm not familiar with the term "exemplar prototype", but stamp.fixed.state
is (if only in implementation) de facto equivalent what is called defaults
in most JS libraries. Based on your response in the issue about the naming of enclose
I understand why you decided against naming it something like initialize
even if that seems descriptive (initializePrivateState
would probably be even more correct, but a bit unwieldy).
I understand that the naming is intentional, but because it differs from the naming used by other JS libraries sharing the same or similar concepts, I don't think their naming clarifies their intent without sufficient background knowledge or an explanation like the one you provided.
Despite having read several articles on the issue, I'm still not entirely convinced that prototypical inheritance is necessarily superior to classical inheritance -- the lack of support for multiple delegate prototypes in JS certainly limits the usefulness of having delegate prototypes in the first place (especially in a library like stampit that wants to provide a mechanism for "type" composition -- I wrote a dummy that uses harmony direct proxies but I'm not happy with that either, nor with the simplified version that only deals with delegation).
I am aware of common convention in the JavaScript community. Unfortunately, a deep understanding of prototypal OO - even an understanding that there is more than one type of prototype - is uncommon. It is my hope that writing about it, speaking about it, and sharing this library will help change that.
Is there a learning curve? Sure. Do I think changing 'methods' to 'prototype' will make it easier to learn how to use Stampit effectively? No.
the lack of support for multiple delegate prototypes in JS certainly limits the usefulness of having delegate prototypes in the first place
There is no useful difference between having multiple delegate prototypes and concatenating multiple prototypes into one, as Stampit does when stamps are composed. Stampit supports inheriting from multiple prototypes as is.
Stampit does support inheriting from multiple delegates, keeping all of them as delegates. That is impossible with classical inheritance, as it is currently implemented in any JavaScrpit library or specification. So by your own criteria, prototypal methods are superior to classical, if only to satisfy your desired capability.
As for "other libraries sharing the same or similar concepts", I'm not concerned because there are none that are popular. The only popularly implemented inheritance libs implement concatenative (calling the method extend or mix in) OR classical.
Neither of those supplies a useful model for a complete understanding of prototypal inheritance, so it doesn't make sense to follow their conventions to describe different semantics.
The naming of
fixed
aside,fixed.methods
acts as the de facto prototype of objects created by the factory:So shouldn't
methods
be calledprototype
orproto
or something to that effect? After all you can pass in other things than methods (e.g. getters, setters and values) and they will behave just like they would on a prototype.I guess a counter-argument is that stampit doesn't really have inheritance (types are instead composed) and prototypes don't seem to provide a sane way to support multiple inheritance.