Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

Which is the problem with "class" in a nutshell.

If you don't understand prototypal inheritance in ES5, you don't use it, and you stick with simpler concepts that work in a clean and elegant way that doesn't depend on OO-like trappings cluttering up your code unnecessarily.

But with that "class" keyword sitting there, it looks vaguely familiar enough, and you just start programming as if it were Java, and your code turns into this complex morass without you even realizing it until the pain starts.



sort by: page size:

The more i read, the less i like :(

The prototypal inheritance example in that post does not read in an intuitive manner, and certainly don't improve the clarity of meaning for prototypal inheritance (especially now that it's using the word "class").

The only compelling thing i can find in here so far is that it's trying to provide common functionality from ES5. But again, i don't see what that has to do with building a language that is easy for non-programmers to grok, making the Javascript semantic model more accessible, or even making JS coding more readable.


ES2015 doesn't have classes, it has a class statement which desugars to prototypal inheritance.

And as Self demonstrated long before Javascript even existed, prototypal inheritance is neither bizarre nor verbose let alone dangerous. As with most other things, Javascript just has a completely mangled version of it for (I can only assume) original implementation simplicity.


The class in ES6 is just syntactic sugar over Object.create. Class is only coming out becuase most people wont learn that javascript has prototypal inheritance, and how to use it. Its a different mental model, in my opinion prototypal inheritance is more expressive and light weight than typical classes from other languages

"Who doesn’t like explicit inheritance, like in Java language, instead of writing magic code for prototypal inheritance?"

There's nothing magical about prototypal inheritance code, and I'd suggest the class keyword is more magical since it's "primarily syntactical sugar over JavaScript's existing prototype-based inheritance" [1]. Furthermore, encouraging classical inheritance constructs without mentioning the classic pitfalls is somewhat harmful [2].

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

[2] https://medium.com/javascript-scene/javascript-factory-funct...


> the "class" keyword was a huge mistake

There is not a single fact proving that statement. People want to write Javascript in different ways, Javascript is no less OO that it is FP. I don't see why one camp should be more privileged than the other.

> prototypal inheritance you will write cleaner code with fewer errors.

JS Classes use "prototype inheritance". compare that :

    function Foo(){}

    function Bar(){
       Foo.call(this)
    }

    Bar.prototype = Object.create(Foo.prototype)

with that :

    class Foo{}

    class Bar extends Foo{}

There is absolutely no debate as to what is more readable, cleaner,easier to parse for IDE, and less error prone. ES6+ is considerably making writing JS easier and safer. There is very little reason today to deal with prototypes directly. And in strict mode, calling Foo or Bar without using new yields an error.

Es2015 classes are just syntactic sugar around prototypically inherited objects. I agree they are nicer to use but under the hood there's no change. Which is why adding all of these oop concepts seems contrary to how the language is designed. At the end of the day JS has no true classical classes.

Not an expert just my opinion.


I think ES6 classes are the worst of all worlds. I know people from a Java background really want classes in their Javascript but this is not that.

ES6 classes look like kind of sort of like a class but if you poke it at all you see lots of sharp edges and weird behaviours that make no sense unless you know what it's sugar for.


While I'm a huge fan of what ES2015 has brought to JavaScript, the "class" keyword was a huge mistake. There are no classes in Javascript, there are only objects. By embracing prototypal inheritance you will write cleaner code with fewer errors.

I think you're mixing up your timelines. ES5 brought `Object.create` and other prototype helper methods. This was a heyday, of sorts, for JS as a prototypal language with Crockford and others trying to explain how prototypes differ from inheritance based classes. However even then the C++/Java model had become too well ingrained by that point, especially at certain very large tech companies.

The `class` keyword was introduced in ES6, which is indeed a kludge on top of prototypes.


Classes are fine if you understand they're just syntactic sugar for the already extremely widespread constructor+prototype pattern.

The primary reason a significant part of the community hates the ES6 classes is that the class keyword is misleading for people who don't understand prototypal inheritance.

The OOP vs FP divide is orthogonal to that as the FP devs in question generally disagree with the constructor+prototype pattern to begin with (and often shun prototypal inheritance entirely).

There's also the people who want JS to be more like Haskell/Lisp, but they've mostly moved to LiveScript and ClojureScript and only occasionally complain from the sidelines.


> - Prototypal rather than classical inheritance,

Meh. Javascript looks, feels and behaves much more like a single-inheritance class-based language (without the class sugar) than like a prototype-based one (Io and even more so Self). Especially if you stick to the standard.

A small concession was made towards prototypal use in ES5 with Object.create (which remains little used and slow as molasses) but it's looking to snap back to classes with ES6


The one about classes is solved by not using classes. Prototypal inheritance works well (and besides, most implementations of 'class-like' behaviour are using prototypes underneath anyway)

I'm playing a bit of a devil's advocate here ;)


Class is a bit of a shambles. Yeah, it does make it easier to create constructors. But it also papers over the underlying prototype inheritance structure and can mislead beginners into assuming there is class system in place.

So classes in ES6 are something I have very mixed feelings about, on one hand all that is being added is syntactic sugar for what is already being done, I'd like to repeat that ES6 classes add NOTHING that isn't already being done and all it really does is pave the cowpath that is being used in places like node

Currently:

    JSONParseStream.prototype = Object.create(Transform.prototype);
    function JSONParseStream(options) {

    Transform.call(this, options);
        ...
    }
   
    JSONParseStream.prototype = Object.create(Transform.prototype);

    Object.defineProperty(JSONParseStream.prototype, 'constructor', {
        value: JSONParseStream,
        enumerable: false,
        writable: true,
        configurable: true
    }

    JSONParseStream.prototype._transform = function(chunk, encoding, cb) {
        ...
    }
With ES6:

    class JSONParseStream extends Transform {
        constructor(options) {
            super(options);
            ...
        },
        _transform(chunk, encoding, cb) {
            ...
        }
    }
That being said, the fact that previously you could not simply use the word class meant that despite efforts of people unused to the language (let me tell you how many half assed class libraries i've seen in code written by people who mainly code in python or java but have some web code as well), unnecessary inheritance tends to be avoided. The lack of a class keyword tends to get javascript writers to avoid inheritance for things best served by mix-ins or object literals, or whatever. I predict that adding the class keyword, while saving me some time will also cause an uptick to unnecessarily convoluted inheritance patterns as new users find they can implement all of their design patterns verbatim without thinking if they really need the ajax method, the json parser, and the url builder to all be in objects that inherit from each other.

Yup. The class keyword is a huge step backward, and it was only put it because of a very different world several years ago when all this was put into motion. It is just a wrapper around prototypal inheritance, but hides a lot of the features in favor of making things look like other OOP languages, even though it isn't.

It is also very debatable if classic OOP is even good at all. JS was heading in the right direction, with more functional approaches, factory based object creation, etc... and now it's all back to square one.

Fortunately I work on a product where most devs have functional programming backgrounds, so the argument isn't too hard to make. But I fear for the community in general.


>Which, as above, is easy! But if there's one actual problem with the class keyword it's that it makes people who know Java think they understand JS inheritance.

Which is totally fine, as for all intends and purposes the behavior is the same. You create new instances, and you call methods on them.

The "movable" context (this) will be a little surprising, but for everything else one can write JS for decades with ES6 classes and "OOP", without having to know how the prototypes, objects and functions they de-sugar to work.


Please, please read http://killdream.github.com/blog/2011/10/understanding-javas...

Prototypical inheritance as of ES5 is really not that hard. Here is the same example rewritten with prototypes: https://gist.github.com/1558929


Sarcasm aside, I know raganwald (you?) can approach things functionally. :P My comment isn't to imply he can't (nor that I'm particularly good at it), nor to imply anything about his choices when writing code (as I said, he correctly notes that this is an issue when trying to write class-centric OOP in Javascript; this says nothing about his views on whether class-centric OOP in Javascript is a good idea or not). And, certainly, come ES6, mixins get some language help with Object.assign.

My point is simply that if in ES5 you have to fight this much with the language to try and shoehorn it into a particular paradigm, maybe you've picked the wrong paradigm for that language. And the fact so many people try, and so many authors have written ways to try and shoehorn that paradigm into the language (as it stands at ES5), tells me that it -really- is probably not the best choice.

And the insistence in doing so seems like a misplaced "make it behave like Java" that brought to mind that URL I linked.

That's not to say thinking about it isn't itself a worthwhile endeavor. That's not to say that seeing that it can be done in Javascript isn't a point in Javascript's favor. That's not to say there isn't a demand by people for the language to behave this way, and that others understandably try to meet that demand. But it is to say that it's solving a problem that is self-inflicted, by dint of choosing to use classical inheritance in a language that was designed to support prototypal inheritance.


JS is such a mess these days.

While do prefer es6 class syntax over protypical inheritance, I have found compatibility and performance to be the issues that prevent me from adopting them wholeheartedly.

next

Legal | privacy