Property vs Behavior inheritance

Axel Rauschmayer axel at rauschma.de
Fri Dec 16 04:22:10 PST 2011


> With object exemplars, you have:
> 
>     var jane = new Person("Jane");
>     var Employee = Person <| { ... };
> 
> (Since I guess only long time readers of this newsgroup could understand what you write above, let me give a capsule summary:
> Employee becomes an object with a .prototype property referring to an object with properties of the RHS and a [[Prototype]] of the LHS. 
> Employee.prototype to inherits from Person.prototype and adds properties in {}.)

No, Employee becomes an object whose [[Prototype]] is Person (see [1]).

> What constructor is invoked if I write:
>   var jack = new Employee(...);

This is roughly equivalent to:

    var jack = Object.create(Employee);
    if (Employee.hasOwnProperty("constructor")) {
        jack.constructor(...);
    }

> Let's just make your example slightly more real. There is nothing to help us avoid this kind of pothole:
>    var Employee = Person <| { hoursPerWeek: 40  };
>    var Contractor = Employee <| { ... };
>    var PartTimer = Employee <| {...};
> The failure mode derives from using object literals for both objects and classes. Experience, review, or debugging have to save us. (I guess we can't require the operands of <| to be capitalized and the RHS to have only functions?).  I don't think we make this error in class-based languages.

How you work with object exemplars is almost like with classes: You have to be aware which objects are exemplars and which ones are instances. A useful sanity check could be to require an exemplar to have a constructor() method.

Note that there are always two steps involved in subtyping:
1. Extend the shared properties.
2. Extend the instance properties.

In Self, you have an instance object O pointing to a shared object S. To instantiate, you clone O (shallowly). To subtype, you create a new instance object O' that points to O and a new shared object that points to S. When you clone O’, you also clone O, so it’s a different kind of reference than the one between O and S.

With object exemplars, #1 is performed by making the super-exemplar the prototype of the sub-exemplar, #2 is performed by implementing constructor() and invoking super.constructor().

> The <| operation solves the same problem that seflish solves: behavior inheritance; they both use object literals (optional in selfish); neither address the data-property specification problem nor the data-property initialization problem.


Yes, you have to know that instance properties are always added in the constructor. But that rule is the same with most class declaration proposals that exist. I don’t find that rule problematic, it’s just not how things are commonly done in mainstream languages – which tend to have a more declarative syntax for instance members.

> Indeed, and perhaps that is my point. Does a classless solution make sense if in fact you have to rigorously apply extra-lingual class-based reasoning to succeed? 

Class declarations can do some interesting things such as make sure that a prototype only contains methods. But even with class declarations, the core point of object exemplars still holds: JavaScript inheritance would be simpler if a class declaration desugared to a prototype (instead of a constructor). [I am ignoring backward compatibility which is a big thing to ignore.] Sect. 3 of [1] argues that point and gives several code examples.


[1] http://www.2ality.com/2011/06/prototypes-as-classes.html

-- 
Dr. Axel Rauschmayer
axel at rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20111216/33a6b140/attachment-0001.html>


More information about the es-discuss mailing list