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

> 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.


sort by: page size:

"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...


> Class inheritance is not a common JavaScript design pattern. It's a hack, used by a minority of JavaScript developers, in a minority of projects.

If you don’t like the way JavaScript’s prototypal inheritance works, take it up with Brendan Eich.

You are simply wrong about the commonness of using prototypes though. Nearly every big JavaScript project is organized around extending and creating prototypes, and making instances via the `new` keyword. It’s only a few zealots who militate against using that feature... and to the detriment of their followers, who end up with code that is slow and a memory hog.


> the "class" keyword was a huge mistake. There are no classes in Javascript, there are only objects

That's true if you define the word "class" to not include JS classes, but in that case, you can use the keyword and still "embrace" prototypal inheritance, since as you say, it's all just objects (even if you use the class keyword).

Alternatively if you use a more flexible definition of the word class, then your assertion is not true, because JS does have classes, they just are implemented via prototypes.

Either way, I don't see how your comment is correct. Is it all objects, or not? :)


> A JavaScript class is syntactic sugar for prototypes, not functions.

Again you're basically speaking into exactly what I'm trying to say. Because what are JavaScript functions? It is also a prototype. I'll try to put it a different way. The JS community has "moved beyond" classes because they are functions. Both classes and functions are prototypes, but functions are often easier to work with, more maintainable and more efficient.

I'm not trying to say that you should never write another JavaScript class in your life. I write them myself when it's prudent to build things in a structure that resembles classical OOP. The reason I don't personally use that sort of coding style, if I can avoid it, is because it's an act. It looks like classical OOP, but everything is mutable at any time which means it's very easy for consumers of the code to break it by accident. This is less of a problem when you build things as isolated modules, based on individual functions, because there simply isn't any complexity to "misuse".

This is sort of similar to why the virtual DOM became so popular in frontend JavaScript. Because it's harder to work directly with the DOM itself. It's not necessarily better to use functions, it's just "safer", because they come with less risk of someone doing something bad by accident down the line.


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.


The point the OP was making that the class keyword was a mistake, not that inheritance was a mistake. This is an entirely different topic.

Furthermore, Javascript classes make writing mixins AKA composition a breeze, compared to before:

http://justinfagnani.com/2015/12/21/real-mixins-with-javascr...

This link is an excellent rebuttal to Eric Elliot article and how he achieve composition through copying by the way.

So even if you like composition over inheritance, Javascript classes still allow you to write safer and clearer and cleaner code. Now you can do away with ugly factories and property copying.

> Object.assign is far less fragile than inheritance

You realize the using Object.assign means copying properties from object to object over and over and increase memory requirements in order to run a script.

So my point still stands, there is not a single disadvantage introduced with the class keyword.


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.

> Classes are pretty nice. It's a syntax sugar which is nicer and easier to understand than using functions and prototypes.

I actually think that this syntax sugar is the opposite of a solution. It has always been tricky getting developers coming in from other languages (mainly C-like, and Java-like) to understand that JS is NOT an object-oriented language, but in fact is a prototypal language.

By adding the class keyword, I think this only confuses those users further.


I don't understand this perspective.. people were already using class semantics in JS before the class keyword; but there was so much inconsistency in the patterns they were using to (ab)use Javascript's prototypal inheritance to emulate classes.

The class keyword brings together a 'best practice' set of pre-existing JS features to provide a uniform OOP experience. Yes, classes still work a little bit differently than they do in other languages, but the benefit of being able to expect the same type of class from modern JS libraries doesn't get appreciated enough.

The only drawback I see to its addition is that it abstracts prototypal inheritance and some other key idiosyncrasies of Javascript from newcomers to the language. But the move away from doing things 'the old ways' has worked out much better for Typescript adoption anyway, as it's hard to type things properly when the interface of an object created by a custom 'class' function is just 'whatever the prototype currently has'


> - 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


> unless you mean prototype based inheritance which is very different beast

All inheritance in JS is prototype based inheritance. The class syntax is just syntax sugar prototypes. In theory you can do all sorts of crazy things with prototypes. In practice people use them just like classes. The reason people don't use inheritance in JS has nothing to do with browser support.


Grand-parent comment asked for an example of an error introduced by using class that would've been avoided with prototype inheritance, and you respond with an "awesome" "curated" list of opinion pieces and conference talks by famous devs and rockstars...

This is what's wrong with the JS community and why everything is so hype driven... this list gives the impression that if you want to be a good JS developer you should've even THINK about trying to use classes in your JS because if you do then you don't truly "get" JS.

Think for yourself and decide if classes will improve your code in the way you plan to use it. Classes have hugely improved my company's JavaScript, it works well considering our developers understand OOP much better than they do functional programming, which I think is pretty common.

We don't rely on inheritance, we reuse by composition (which is just as easy to do with class as it is to do with protypes).

Classes are fine! Use them if you want to! Don't use them if your existing code relies heavily on prototypal inheritance, but if you just wanna wrap some methods around some internal state and you like the way the class syntax looks compared to the prototype syntax don't let some think piece on medium try to convince you that classes are bad.

EDIT: sorry to go off on a slightly OT rant on your comment... I just got frustrated by the link you posted.


> No. Just no. Simpler is better, especially if there are no real drawbacks.

Your claim of "no real drawbacks" is very much your opinion, nothing more.

> Yet you just dismiss my approach without providing solid argumentation

I've made several other comments on this item.

> you cannot use previous OOP experience

Shock horror, a developer needs to learn JavaScript before writing JavaScript. This is a positive not a negative. There are already too many "developers" who write javascript without understanding it.

> there are MANY ways to do OOP using prototypes (functions,direct prototyping,__proto__) vs ONE

your example of "many ways" is misleading: it's not "functions" or "direct prototyping" - you assign functions to a constructor's prototype, and they become instance methods.

__proto__ is non-standard, and no developer worth working with would use it for creating "classes".

There are also MANY ways to create "classes" using object literals - the article linked just gives one example of this.

> 'this' has different meanings depending on context -> requires you to process contextual information

you're making a mountain out of a molehill.

> prototypes make existing objects unreliable ->

How so?

> requires prior knowledge about libraries and APIs (leaky abstraction)

No more than an object literal with methods attached to it.

> building an object with prototypes requires far more mental steps: you have to know about objects, functions but also about the prototype chain, the hidden prototype property (why?), the logic behind the new keyword etc.

Yes, it's so horrible that developers using a language need to have some knowledge of that language before writing more than basic code, isn't it?

> If prototypes had been implemented in a very consistent way (without the new-keyword and only using __proto__) I would have advocated prototypes instead of literals

you still haven't actually given any reason the new operator is "bad".

and you keep mentioning __proto__ which makes me think you don't understand the language at all. __proto__ is a non-standard property that some implementations expose

> On top of this, many different 'sugar' solutions exist, most of them incompatible.

You don't need "sugar" at all - just a constructor function definition, any methods for the prototype and then as many calls to instantiate objects as required.

> conforms to established industry and business standards in OOP

buzzwords and "make the boss happy" phrases mean nothing here.

> requires less knowledge about language details, this leaves much more room to focus on application logic and design

if the developer doesn't understand javascript, which OOP pattern you use is the least of your worries.

> very transparent, no sugar code (beget) or libraries required as I said, no sugar or libraries are required for prototype "classes" - it's part of the language you are choosing to ignore.

> neat code: methods are grouped together

How is this different to assigning methods to a constructor's prototype?

> allows to implement well known design patterns easily

this is a pattern in and of itself, what are you talking about?

> no this, that or self variables

a lack of "this" is not an advantage - you mentioned earlier about not being able to re-use previous OOP experience, then argue that not using a standard OOP concept ("this" in instance methods) is a good thing?? Make up your mind!

> And all you are saying is: it's too easy, it must be for entry level developers.

No, I said "simpler is not always better". Your approach ignores huge parts of the way JavaScript works because "it's too hard".

It's nothing to do with puzzle contests or ridiculous languages - it's about learning to use a language to it's full potential, rather than sticking your head in the sand and saying "it's too hard, so I'm not going to do it!".


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

Which is not new with Javascript in general. every single feature in javascript suffers from being strangely familiar while having a behavior specific to Javascript. Comparison operators, var declaration hoisting,function declaration hoisting, "this", "typeof" operators,type equality and coercion rules, and co, all require to actually learn how the language works. This isn't a very good argument against the class keyword. Yes, developers who use a language need to learn it before hand. It applies to all languages.


> those who don't use it are often forced to take it into account in their code; especially library authors.

No, `class` is syntactic sugar for the most common way of doing classes in ES3 and ES5. There is no semantic difference between:

    function Thing () {}

    Thing.prototype.greet = function () { alert("hello"); };
and

    class Thing {
      greet () {
        alert("hello");
      }
    }

They are the same, so it introduces no new traps for library authors.

> JavaScript still only has prototypal inheritance; class syntax is just sugar[1].

Sure, but the patterns you use with the class syntax are incompatible with the patterns you use when using object literals, so libraries pick one or the other, typically the class way.

> Even with arrow functions, which don't change the binding of "this"[2]?

Even with arrow functions, `function` still exists ands is more frequently used.

> Trying to access a nonexistent variable throws a ReferenceError[3].

var a = {};

var b = a.c;

Doesn't throw a ReferenceError for me.


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.

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.


There was plenty of outrage when classes were added to JS. “JS uses prototypal inheritance, not OOP!”
next

Legal | privacy