3 ms·
Well, the problem is that you're trying to bring analogies over from classical inheritance that don't directly apply. We're trained in classical languages to th
by mistercow 15y ago
Well, the problem is that you're trying to bring analogies over from classical inheritance that don't directly apply. We're trained in classical languages to think of classes as being these blueprints in a strange hierarchy of blueprints and a "constructor" is this weird method by which a class transmutes itself from the abstract to the corporeal, producing an "instance".
In prototype-based OO, a constructor is just a function that builds an object. If you like, you can give that function a starting point for building its objects (the prototype), but in the end, it's just a function that builds an object. It's conceptually not that similar to a class in classical OO, even though you can use it to implement classical inheritance.
And that's really the core of the problem: read any book about JavaScript, and the first thing they'll probably tell you after introducing prototypes is how to get something like classical inheritance hierarchies by chaining prototypes together. So people end up thinking "what a strange and roundabout way to handle classes", when the problem is that they shouldn't be thinking about classes in the first place.
And here's the elephant in the room: long prototype chains are not usually the right solution because long inheritance chains in general are not usually the right solution. Classical inheritance just makes it so easy to build elaborate and beautiful hierarchies that most people never realize that doing so is usually just adding complexity for no real gain.
- jarek-foksa 15y agoIn prototype-based OO, a constructor is just a function that builds an object. If you like, you can give that function a starting point for building its objects (the prototype), but in the end, it's just a function that builds an object. Isn't this called pseudo-classical inheritance? In purely prototypical inheritance one object inherits from another object, there is no need for constructors whatsoever, instead you are just setting __proto__ link so that it points to the object from which you want to inherit. This way you have much more freedom - you could add initializer method that sets up variables in a similar fashion to constructor, but you could also easily implement singleton or mixin patterns. Ideally, prototypical inheritance would be done like in the code below, but I doubt we will ever see this supported by JS: obj1 = { __proto__: Object.prototype, init: function() { } } obj2 = { __proto__: obj1, init: function() { super.init() } } obj3 = {} obj3.__proto__ = obj2 obj3.init()