Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Well, I have to argue that it's not the same pattern. I think the problem is that you still like to believe that js has classes, which it doesn't: js has got objects only. That it also has constructor is an (admitted?) historical mistake. Just think of all the weird crap that goes on to make `new func()' work and produce a new object.

What is no mistake is the refreshing change of view you get when you start embracing objects and prototypal inheritance. See for example the traits library[1, 2].

[3]: Is a cursory introduction to Self, with another points example :)

[4] Contains an example of my own (heavily inspired by Self and Io). I have stitched together various internet sources to come up with `clone', an operator assisting in differential inheritance.

[1]: http://traitsjs.org/

[2]: http://code.google.com/p/es-lab/source/browse/trunk/src/trai...

[3]: http://www.cs.aau.dk/~bt/DAT5E08/MarkusKrogh1.pdf

[4]: https://gist.github.com/997910



Traits aren't incompatible with classes at all. In fact, Tom van Cutsem, the author of traits.js worked on the class proposal that's going into Harmony.

Aside from the simplicity argument, I didn't see anything in Markus's presentation that showed an advantage of prototypes. His point example is cloning a point and then immediately replacing all of the state, so there's nothing there that classes couldn't do (in less code).

Your gist (especially the color point) is an example of using prototypes in a way that's hard with classes. Fortunately, adding classes to JS won't hurt that at all. You could just as easily do:

    class Point {
      constructor(x, y) {
        public x = x;
        public y = y;
      }

      add(other) {
        return new Point(this.x + other.x, this.y + other.y);
      }
    }

    let p1 = new Point(0, 0);
    let p2 = p1.clone({
      color: '#green',
      toString: function() {
        return this.color + ': ' + uber(this).toString();
      },
    })
In other words, adding classes to JS won't take away anything already there. It just gets a really common pattern and makes it much less verbose. The idea is to pave the common path of class-like inheritance, but not to build a fence around it to keep you in.


Object.create(...) is a factory pattern. "Object" is suddenly a factory for making anything, you just supply the blueprint in the form of "Point." So to know what will happen, I need to look at Object and at Point. One strength of this pattern is when I want to handle cross-cutting concerns in the factory. For example, I can modify all objects created with aspects if I use a factory to create them. Or I could have the factory decide whether it is creating Plain Old Javascript Objects or whether each object is backed by persistent storage a'la ActiveRecord.

A factory is very different from a keyword baked into the language. The new keyword suggests that the underlying language is doing the construction, and all of the details about the object being created are encoded in its blueprint, "Point."

I consider a factory and a keyword to be two very different patterns regardless of whether you want to call them class-based or prototype-based.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: