12 ms·
Prototypes Are Not Classes
- ossdev1 13y agoNever get why people are so excited with atomization, that necessity of decomposing everything in atomic parts...
- raganwald 13y agoSome people just want to watch the world burn. Others are curious. What is fire? Is electricity fire? What's the smallest thing That can be on fire? How can you make something burn faster? We make up little explanations about how knowing the answers to these questions makes us more productive world-burners, but in the end we're just curious people.
- gwright 13y agoI think the decomposition is important but not necessariy that you have to continue that process until you have atomic parts. Understanding the decomposition allows you to internalize the behavior of a complex entity and thus understand and predict how it will behave in different (i.e. previously unseen) contexts. If you avoid decomposition and instead view each entity as a one-off with its own unique behavior patterns then you are limited to memorizing the behavior on a case-by-case basis. Any extrapolation or prediction of behavior would be as effective as random guesses.
- deleted 13y ago[deleted]
- pjmlp 13y agoI guess before learning JavaScript, developers need to be sent to a Self learning camp.
- raganwald 13y agoWould that make them... Self-aware? I'll just show myself out...
- masklinn 13y agoI'm not sure that's a good idea, because then they'd be made very sad by constructors, by prototypes being something completely different[0], by not having mixins[1], by single-inheritance, by dynamic inheritance[2], by the lack of blocks (and non-local returns), etc… Essentially, by javascript not being a very good Self. [0] IIRC in Self the prototype is the object you copy, objects linked through parent slots are either mixins or traits. [1] although it doesn't have a lobby, which makes the difference between traits and mixins, js's prototypes are probably closer to self's traits. [2] that's being added in ES6, yay. But still single, boo.
- angersock 13y agoMI still sends shivers down my spine, having spent time in the C++. Just say no.
- clhodapp 13y agoSo C++ got multiple inheritance wrong... That doesn't mean it must be rejected in all cases.
- angersock 13y agoWhat are the cases where MI is better than mix-ins or component architectures?
- pjmlp 13y agoMaybe just in some corner cases. However Eiffel, OCaml and Python MI implementations seem to be implemented in a more sane way.
- raganwald 13y agoNewtonScript had a neat concept of heterogeneous multiple inheritance: Its "objects" had a prototype-like inheritance chain and a container inheritance chain. If client-side JavaScript had this design, there would be no need for the DOM to have a special event mechanism that lives outside of method handling: DOM elements would simply have method handlers and the dispatch system would handle prototype and container inheritance.
- rtpg 13y agoThis sort of realization is the first step to realizing that you really shouldn't be writing javascript like java/C++. It makes things feel a lot nicer when you start really thinking in JS. I'd recommend checking out Crockford's "Crockford on Javascript" series for some good intro on thinking about Javascript (http://www.youtube.com/watch?v=JxAXlJEmNMg http://www.youtube.com/watch?v=JxAXlJEmNMg). Section 3 is where you really start talking about JS. For a good counter-example, check out a lot of google's JS libs (in all their giant module goodness).
- lispm 13y agoJesus, the language is called Smalltalk. Not SmallTalk. Btw., in a typical language supporting prototypes, I would expect that prototypes are nothing special. Every object could be a prototype for others...
- klibertp 13y agoThat's true in JavaScript - there's an Object.create() method, which creates new object with any other object set as prototype: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... There is a problem with accessing prototypes of objects, as they are not exposed to the user and only available through internal property __prototype__ (IIRC). And there's quite a bit of magic involved with constructor prototypes, which - again - makes it impossible to traverse prototype chain unless you create your objects yourself and store the references yourself. So yeah, prototypes are nothing special in JS, but their API kind of sucks and could get better. Object.create is a step in the right direction IMO.
- masklinn 13y ago> There is a problem with accessing prototypes of objects, as they are not exposed to the user Actually, Object.getPrototypeOf was added in ECMAScript 5.1. It's even supported by IE9. > only available through internal property __prototype__ (IIRC) It's an external property (the internal one is `[[Prototype]]`_, and is called `__proto__`. It's non-standard, although all modern browsers implement it (even IE11, but not IE10)
- klibertp 13y ago> the internal one is `[[Prototype]]` I was thinking about this one. > Actually, Object.getPrototypeOf was added in ECMAScript 5.1. Wow. Thanks, I wasn't aware of this.
- raganwald 13y agoAnd weirdly, I often miss-spell JavaScript as "Javascript." No idea why.
- CmonDev 13y agoGood (enough) for GUIs, bad for business logic.
- mlex 13y agoI hate to be _that_ guy, but I found the grey on light-grey text to be difficult to read.
- kyberias 13y agoThe author has to emphasize that prototypes and classes are a different concept at least five times in the article. Why? Because the explanation is long-winding and weak.
- raganwald 13y agoThis is the best feedback so far.
- pygy_ 13y agoHow about this for an abbridged version? "You can add methods to any objects (no metaclass required), and any object can be inherited form, becoming the prototype of its descendants. In other words, any object can perform the job of a class in a class-based language."
- dognotdog 13y agoTL;DR: long winded bad analogy, but maybe helpful That doesn't sound quite right to me. Not that it is wrong, but maybe looking at it the wrong way? For the discussion, I propose an object has some state, and can receive messages and send messages in response. A class is the abstract idea of what an object should be like. To break out the bad analogies, it's like ordering from a restaurant menu. You ask the runtime for an instance of a class. If you want something special, you have to have it put on the menu first. Prototype restaurants have no menus, but they have the dishes on display, and you can order those. Or, if you're so inclined, just point at your neighbours' food and order what that guy's having. If he's eaten half of it already, you'll only get as much as he has left, but luckily you can add combine it with other dishes or ingredients as you go. You can see that if we put some rules in place about which objects can be copied, and what happens during copying exactly, and we call some special objects classes, and use them to create other special objects we call instances, a prototype-based object system can be made to behave like any class-based object system. If we bake those special rules into the language, we make the computer's job easier with hard-wired shortcuts.
- xmonkee 13y ago
- roel_v 13y agoEvery time someone tries to explain why prototypes are so very much not classes, I can't help but come away thinking 'yeah potato/potato - so they're basically the same'. Be it Crockford, this guy, any of the 100 articles you find only when you go looking for it. Sure the nuances between languages are different, big deal - what is called 'class' in a dynamic language is very different from what is called 'class' in C++, yet everybody calls them classes and doesn't go around writing articles about how runtime-modifiable object blueprints really are fundamentally different from those that are set in compile time.
- raganwald 13y agoDid you read TFA or simply fold it into an airplane and launch it towards the dustbin? 1. This is not a dynamic vs. static thing, the languages cited in the article with classes are all dynamic languages. Metaobjects are typically found in dynamic languages like Common Lisp and Smalltalk. 2. The difference between a class as described in this article and a prototype is the same as the difference between a C struct or Pascal record and a Smalltalk object. I do recall people saying "potato/potato" about that when OO was first going mainstream, but I think over time people accepted that encapsulating private state is more than a nuance. Your Milage May Vary.
- roel_v 13y agoYes I did read it, several times even, because I really want to understand it if there is a difference. This is why I could remark what I did - because I've actively looked into explanations of the difference, several times, over the last year or so, and walked away with the same conclusions every time. My point is that the more I try to understand other people's explanation, the more I think it's just semantics. To put it in your terminology as used in your post, it seems that you are redefining what is commonly and in a broad sense known as 'classes' as 'metaobjects' as a generalization of different ways to implement classes. Which is fine, when you look at the details, but to me the difference doesn't warrant overloading a well-known term like 'class'. (Although I'm still not clear what you'd call a C++ class, if it's not a meta-object as your reply suggests.) To stay with your C/Pascal vs Smalltalk example - I'd be perfectly fine calling a C struct a 'class' when doing object-oriented C, for example as done in GObject (from GLib, one of the Gnome base libraries), and calling a Smalltalk class also 'class'. 'class' is a malleable OO concept, and its exact implementation isn't all that important or interesting conceptually, and is certainly not tied to one specific implementation of the concept. I still don't see how the Javascript 'implementation' (I put this in quotes because most things in Javascript are just accidents derived from design decisions that put a high premium on ease of implementation, which BTW is usually how I like it, I'm not knocking on JS for that here) of classes is so different that it warrants its own name ('prototype'), suggesting it's completely different from 'classes' (and not only that suggestion, but also people claiming that they're 'very' or 'fundamentally' different - not saying your claim is that strong, I can't really tell from the post, just that some people do).
- Jare 13y agoI've never heard anyone, experienced or newbie, say "JavaScript has classes". People at best will say "You can sort of make classes in JavaScript using objects". To me a Class has always been "a family of objects with the same structure and behaviour, and a way to create them". Stuff like hiding, constructors, type checking, polymorphism and inheritance are interesting, but secondary details. But then, I was taught OOP using Modula-2 back in '89, so I'm used to the idea that language features and paradigm features need not match 1:1
- roel_v 13y agoYour first and second paragraph seem contradictory to me. Javascript, through what is called 'prototypes', has "a family of objects with the same structure and behaviour, and a way to create them", and varies only in implementation and semantic details from other languages. So I agree with your second paragraph and would say that JS does have classes, but then I'm not sure what your first paragraph means.
- Jare 13y agoYou can use objects and prototypes to build classes, but they are not classes by themselves. Similar to how you can use objects to create a linked list, but the language itself does not have linked lists.
- egil 13y agoYet another shallow article describing the difference between prototypes and classes. Does anybody know of more in depth ones that also discusses multi-leven inheritance, polymorphism etc?
- raganwald 13y agopolymorphism is actually orthogonal to the ideas around metaobjects like classes. They are both powerful ideas. but can be expressed in different ways. Languages like Common Lisp and Haskell allow you to express polymorphism entirely through overloading of functions, for example.
- CrossEye 13y agoI think there is a serious problem in vocabulary. Wikipedia's definition of class ([1]) is quite reasonable, which, slightly paraphrased, reads, "A class is an extensible template for creating objects, providing initial values for state and implementations of behavior." While typically we don't use prototype objects for default state in Javascript, we always can if we choose, and they are widely used for providing behavior. And both "extensible" and "template" fit well. So by this definitions, prototypes really are classes. But almost everyone who comes to Javascript from a class-based language brings a number of additional preconceptions. I don't know the Ruby community well enough to know if your descriptions are accurate, but I know that many of those coming from Java or C# backgrounds expect classes to be (1) distinct creatures from objects (and those who know much about the reflection class Class understand that the objects of that class are objects and not the classes themselves), (2) design/development/compile-time abstractions separate from the run-time realities, (3) unchanging at runtime (which is obviously different from Ruby), and (4) the enforcers of access policies of instance methods. None of these things are true for Javascript prototypes. So to these people, it's easiest to explain that Javascript does not have classes. I have never implemented a serious programming language. But I understand from those who have that implementing classes and implementing prototypes can be very, very similar processes. So, while I won't stop insisting to those from other languages that Javascript doens't have classes, I do recognize that I'm talking more to their preconceptions and not to the deepest truth I know. [1]: http://en.wikipedia.org/wiki/Class_(computer_programming)