An experiment using an object literal based class definition pattern

Allen Wirfs-Brock allen at
Fri Aug 5 15:29:28 PDT 2011

On Aug 5, 2011, at 12:14 PM, Brendan Eich wrote:

> On Aug 5, 2011, at 9:32 AM, Allen Wirfs-Brock wrote:
>>>> I did something similar in my first go at this, but there is a problem...
>>> Right, the desugaring from class syntax is fragile and error-prone.
>> I not so sure I agree.  It isn't obvious that this code pattern is particularly any more fragile, error prone, or less toolable than some of the class syntax alternatives that have been discussed.  Particular, if a programmer sets up an editor template that inserts:
>> const classname = subclass <| function ( ) {
>>    super.constructor();
>>    this.{
>>    };
>> }.prototype.{
>> }.constructor.{
>> };
> Let's count the hazards and costs:
> 1. No hoisted binding.

I think hoisting classes may be problematic anyway.  Hoisting really isn't need to make forward class references from within method bodies work.  Outside of methods bodies hoisting allows oddities such as:

class First {
  partner: new Second();  //or what ever a data property definition looks like in a class def
  defaultInstance: new First;  //is this legal

class Second{
  constructor() {
     this.friend = First.defaultInstance;

or even inheritance circularities.  It isn't obvious to me that there is any actual utility in hoisting class declarations.

> 2. Boilerplate overhead of "const D = B <| function" vs. "class D extends B": 1+2+8=11 vs. 7 (ignoring spaces). Arrow function syntax helps but you still end up with <|...-> cussing.

I'd argue that the verboseness of "function" is largely an orthogonal issue.  Because <| requires (currently) a literal on the RHS the "function" keyword could conceivably be dropped in that context.  However, I don't think I'd want to advocate for that.  In the end, I don't that 4 does 4 characters would be a significant issue for anybody.

(BTW, does it bother anybody that the meaning of "extend" to mean "subclass of" in such class declarations is quite different from what seems to be the most common meaning (add properties to an object) of a function named "extend" in JS libraries and frameworks.)

> 3. As you already mentioned contra Axel, one cannot transpose .prototype. and .constructor. parts. Worse, if you don't have class methods, you have to end with a runt .constructor followed by a ;.

My argument is that once you learn the pattern this isn't an issue.  Certainly, I didn't find my self having any issues with this when writing the collection code.  But, if this is really a work for you, here is a possible solution.  Define this function:

function Class(anObj) {
   if (anObj.hasOwnProperty('constructor)) return anObj.constructor;
   return anObj;

You could even put it as an export into a built-in module.

You can then say:
const C=Class(A <| function B() {

or put the constructor methods before the prototype methods if you prefer).

> 4. Braces required instead of no braces for section labels.
I agree that there is a small cost associated with composeable primitives. But also that the composeability is worth the cost.
>> It isn't clear why this is necessarily any more fragile (or less temptable) than for example:
>> class classname extends superclass {
>>   constructor() {
>>     this.  =  ;
>>   }
>> prototype:
>> class:
>> }
> Really? Item (3) is a big hazard. Readability is harmed by the cussing and bracing. The class syntax may not be the best sugar, but it is sweeter and (due to the order requirement of .prototype. before .constructor., and the mandatory .constructor at the end if you don't have class methods) safer.

I think the Class function I suggest above could be an answer.  But exploring this was my motivation in writing a significant amount of code using my pattern.  I personally didn't find it awkward, error-prone, or to present any readability issues.  But that is all subjective.  If somebody should translated that corpus into class declarations we can do a side-by-side comparison of readability.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list