Settings

Theme

Improving EcmaScript5 OO with sugar

raynos.org

16 points by Raynos 14 years ago · 12 comments

Reader

raganwald 14 years ago

“There are multiple similar prototypical OO utilies... All solve the same problem:”

http://xkcd.com/927/

  • RaynosOP 14 years ago

    For the record, I didn't write this library because I thought I could do it better.

    I wrote it because I didn't know about these other utilities / tools.

mrspeaker 14 years ago

I hope ES.next gets a bunch of the goodness that is outlined in Harmony - this would mostly eradicate the need for stop-gap libraries like pd, or transpilers like CoffeeScript. http://wiki.ecmascript.org/doku.php?id=harmony:object_litera...

And being able to do

    var obj = protoObj <| { ... properties ... }
would be fantastic. If I that, and short function syntax then I'd be happy.
  • RaynosOP 14 years ago

    You need all three I'm afraid.

    We need an easy way to mixin/extend objects.

       var obj = protoObj <| mixin({ ... properties ... }, mixinA);
    
    We also need a solid way to create instances.

       object.create(obj);
       obj.constructor();
    
    is just too verbose. There is some talk around making `new` work with object exemplars which would be great.
Autre 14 years ago

Maybe I overlooked, but is there support for "super.method()" or something along those lines?

  • RaynosOP 14 years ago

    super is a nightmare to emulate and get "right". It has a bunch of weird edge cases you don't really want to think about.

    I promote code like

        var Cat = Object.make(Animal, {
          constructor: function() {
            Animal.constructor.apply(this, arguments);
            ...
          },
          walk: function() {
            Animal.walk.apply(this, arguments);
            ...
          }
        });
    
    Now compare:

    - Animal.walk.apply(this, arguments);

    - this.super.apply(this, arguments);

    - this.super.walk.apply(this, arguments);

    Using super doesn't fix verbosity, it only fixes hard coupling of Child class name to Super class name.

    For the complexities, edge cases and performance penalties a super implementation gives, it's simply not worth fixing this hard coupling.

    If you know of a super implementation that _just works_ please [Leave an answer on StackOverflow](http://stackoverflow.com/questions/8032566/emulate-super-in-...)

    • glenjamin 14 years ago

      I've been getting along fine with nothing but util.inherits from NodeJS.

      Are there any real advantages to the "set the prototype to this object" approach versus building it up by assigment?

          function Animal(legs) {
              this.legs = legs;
          }
          Animal.prototype.speed = function() {
              return legs * 10;
          }
          
          util.inherits(Dog, Animal);
          function Dog(name) {
              this.constructor.super_.call(this, 4);
              this.name = name;
          }
          
          Dog.prototype.speed = function() {
              // I don't disagree that more sugar here would be good
              return this.constructor.super_.prototype.speed.call(this) * 2;
          }
      • RaynosOP 14 years ago

        What your showing is ES3 OO sugar.

        The problem I have is that the notion of a constructor function goes against prototypical OO.

        In prototypical OO we just have objects and objects inherit from objects. there is no notion of a constructor function.

        Also note that pd.make returns an object rather then a function.

        It's simply a programming style I like, to think of my "class" object not as the constructor function but as the prototype object.

        Not to mention that `x.prototype.foo = ...` is ugly.

            var Animal = {
                constructor: function () {
                    this.legs = legs; 
                },
                speed: function () {
                    return this.legs * 10;    
                }
            };
            
            var Dog = pd.make(Animal, {
                constructor: function (name) {
                    Animal.constructor.call(this, 4);
                    this.name = name;
                },
                speed: function () {
                    return Animal.speed.call(this) * 2;    
                }
            });
    • Autre 14 years ago

      Yeah, it gets really hairy, really quickly.

      Beyond the need for calling the constructor (which I'm currently viewing it as an unnecessary hidrance [objects are already initialized]), Object.getPrototypeOf may provide a way out - but maybe not the way you intended. Have you considered it?

      • RaynosOP 14 years ago

            Object.getPrototypeOf(Child).constructor.apply(this, arguments);
        
        Works, but is even more verbose. However if you use Object.getPrototypeOf on this you fail the recursive problem in nest super calls. Read the stackoverflow euestion
        • Autre 14 years ago

          I was deliberately excluding the constructor situation. I should have made that clearer in my previous comment. I think the way out of the constructor mess is not to require them at all.

          I do think the Object.getPrototypeOf approach is feasible for methods.

          • RaynosOP 14 years ago

            the method fails for the exact same reason.

            If a single method calls a super method and that method calls another super method then it fails.

                Object.getPrototypeOf(this).method
            
            Always have one value and only one value, calling it more then once leads to infinite recursion.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection