4 ms·
This seems rather un-self-aware. Yes, "class Food { etc. }" feels more intuitive to you than how it works in JS because you learned on the classical inheritance
by mistercow 15y ago
This seems rather un-self-aware. Yes, "class Food { etc. }" feels more intuitive to you than how it works in JS because you learned on the classical inheritance pattern. But classical inheritance is not fundamentally easier to understand than prototypical inheritance. You've just used it for so long that you don't remember what it was like to see it as a newcomer.
If you want to be fair, this should be called "the problem with OO programming", and the summary of the problem is that it's complicated and requires that you learn a lot of counterintuitive concepts.
- romaniv 15y agoI've started programming in JavaScript before or at the same time I started programming in Java and still find that the author's argument is mostly valid. It's not a matter of habit, it's a matter of consequences and the amount of knowledge you need to have to make basic language features work correctly. Prototypes are simply more complicated than classes. They change behavior of objects, whereas classes _define_ behavior of objects. The syntax doesn't help it either.
- bryanlarsen 15y agoThat's your opinion. My opinion is that prototypes are simpler than classes. The distinction between a class and an object can be very tricky, especially once you get dynamic or introspective because then you run into the situation where classes are also objects.
- romaniv 15y agoIf it was simple, there would be no articles about "proper" ways to construct objects and arguments regarding whether using the "new" keyword is a a bad practice. It's absolutely ridiculous that such core language features need to be discussed and argued about so much.
- mistercow 15y agoThey don't need to be discussed and argued about. If the irrelevant flamewars are to be the standard by which a language is judged, then the only language that will ever pass muster is the one that is never released.
- batista 15y ago>That's your opinion. No, that's an objective statement, on which the creator of the language and some of the greater gurus of it, agree. >My opinion is that prototypes are simpler than classes. Not in the way prototypes are implemented in JS. The creator of the language was apologized lots of times for it's many warts (due to lack of design and time constraints plus limited initial scope for the language), and the greatest of its' gurus had to write a book called "Javascript, THE GOOD PARTS". Someone who cannot see the flows of Javascript's implementation of prototype inheritance, seriously cannot assess good and bad software design.
- mistercow 15y agoFirst of all, I'm not sure it's right to call Crockford "the greatest JavaScript guru". That's a stretch, to say the least. Secondly, you appear to be claiming that Crockford offers strong criticism of JS's inheritance model in The Good Parts. If that's what you took away from it, I think you would do well to reread that chapter. Of course JS's inheritance system is imperfect just like that of pretty much any other language.
- batista 15y ago>First of all, I'm not sure it's right to call Crockford "the greatest JavaScript guru". That's a stretch, to say the least. Well, he sure is on a very short list of js programmers. Who other can you add? Maybe Resig? Ashkenas? >Secondly, you appear to be claiming that Crockford offers strong criticism of JS's inheritance model in The Good Parts. If that's what you took away from it, I think you would do well to reread that chapter. No, I'm saying that Crockford doesn't like the way prototypal inheritance is implemented/exposed in javascript --not that prototypal inheritance is inherently bad. He even writes that the basic action of getting prototypal inheritance is not first-class in js: "In a prototypal system, objects inherit from objects. JavaScript, however, lacks an operator that performs that operation." And in order to use prototypal inheritance he has written a wrapper function to hide all the inheritance boilerplace correctly. (As has every other js programmer I know of, using several patterns).
- mistercow 15y ago> Prototypes are simply more complicated than classes. Only if you try to make them act like classes.
- blinks 15y ago> Prototypes are simply more complicated than classes. [citation needed] I'd argue the opposite: "Prototypes are simply more _intuitive_ than classes." OO-design says that X is-a Y is-a Z, with inheritance providing the main form of structure. Prototypical-design says that X is-like-a Y, but with these differences. This NPC (specific, X) is like any other NPC (general, perhaps the original NPC prototype), but with the name Fred and this custom AI code. They're different ways of thinking, but prototypes are certainly not more complicated than classes in the general case. ---- As for the syntax, though, I totally agree with you.
- mistercow 15y agoThis is a bit of a nitpick, but prototype based programming is still OO.
- tiles 15y agoTo be fair, the list of issues are what someone from an OO background will eventually run into when using JavaScript, and the article does offer solutions to those issues for people who want them fixed (namely cross-compilation, or models for dealing with small or large projects). That said, people using JavaScript should be playing to JavaScript's strengths, or picking a different (if not cross-compiled) platform. It's bizarre that people from fundamentally different programming backgrounds complain about these issues. If you don't like C, don't use C. If you don't like JavaScript, write a native application, or cross-compile. There are options, they're in heavy deployment on several major websites, use them. Then everyone can pick the platform they're most comfortable with.
- tiles 15y agoTo be fair, the list of issues are what someone from an OO background will eventually run into when using JavaScript, and the article does offer solutions to those issues for people who want them fixed (namely cross-compilation, or models for dealing with small or large projects). That said, people using JavaScript should be playing to JavaScript's strengths, or picking a different (if not cross-compiled) platform. It's bizarre that people from fundamentally different programming backgrounds complain about these issues. If you don't like C, don't use C. If you don't like JavaScript, write a native application, or cross-compile. There are options, they're in heavy deployment on several major websites, use them. Then everyone can pick the platform they're most comfortable with.
- crazygringo 15y agoI mostly agree, but it has always struck me as bizarre that to define something like a "class" you wind up defining a function. Sure, that function works like a constructor together with new(), but even after all these years, it still strikes me as a bizarre language choice.
- MatthewPhillips 15y agoA constructor is a function, in every language, JS is just the only one that acknowledges it.
- mistercow 15y agoWell, 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()
- chc 15y agoThe trouble goes deeper than that. Prototypal inheritance in itself probably wouldn't be all that confusing for these people — it's actually a simpler concept than classical inheritance. The issue with JavaScript's object system is that it's downright convoluted. AFAIK, Self is the progenitor of prototype-based OO. In Self, the way you create a new object is just `someObject copy`. You can dynamically change its prototype later if you want, too. But in traditional JavaScript, you can't do that. You want an object? You need a constructor. Instead of just cloning a prototype, you have to do the whole `function Foo() { blah blah.prototype = someObject blah blah }; myFoo = new Foo()` rigamarole, and there is no standard way to access an object's prototype. JavaScript has finally got the equivalent of Self's object creation with Object.create, but that is pretty new — and the actual object system still has the whole wonky prototype/constructor/__proto__ mess behind the scenes.
- MatthewPhillips 15y agoObject.create doesn't have the constructor bit at all. Try for yourself, create an object from another using Object.create and see if the second is an instanceof the first (it's not).
- ender7 15y agoThe problem with Javascript's prototype system is that it's not a real prototype system - it's a chimera that's halfway between a traditional prototype system like Self and a class system like Java. The result is a system that is fit for neither paradigm. Trying to do work in either one requires a lot of extremely counter-intuitive lines of code that 'you just have to learn'. Unless you want your code to get bogged down such lines, you end up using libraries that allow you to write something that looks more like either Self or Java. So, the problem isn't that people haven't bothered to learn 'the right way' to do protoclasses in Javascript. The problem is that 'the right way' is stupid. Either make a real prototype system or a real class system (or both!). But the reason that everyone is so unhappy with the state of things is because it sucks.
- batista 15y ago>This seems rather un-self-aware. Yes, "class Food { etc. }" feels more intuitive to you than how it works in JS because you learned on the classical inheritance pattern. But classical inheritance is not fundamentally easier to understand than prototypical inheritance. Classical inheritance IS easier to understand compared to how prototypical inheritance was implemented in Javascript --and it's obvious from the examples he gives, and all the workarounds to use prototypical inheritance correctly in all the major JS frameworks. The implementation details of prototype inheritance should not leak to the language, but in JS, they do.