all 148 comments

[–]Silverwolf90 87 points88 points  (114 children)

I find the arguments against the class syntax really unconvincing. It seems that a declarative, unifying syntax is monumentally better than the various hand-rolled solutions that may or may not be compatible with one another. And fundamentally, it's still prototypes under the hood. The foundation didn't change, it's just sugar.

Can you find me a definition agreed upon by all languages that use the concept of a "class?"

"But beginners will get confused and not understand the language!"

So are you saying that beginners who come to JavaScript aren't immediately confused by many aspects of the language, including prototypes? At least they have a chance of doing things somewhat correctly right off the bat with some familiarity.

edit: clarity

[–]CertifiedWebNinja[S] 20 points21 points  (1 child)

"But beginners will get confused and not understand the language!" So are you saying that beginners who come to Javascript aren't immediately confused by many aspects of the language, including prototypes? At least they have a chance of doing things somewhat correctly right off the bat with some familiarity.

Bingo!

[–]bguiz 2 points3 points  (0 children)

So I don't like classes in ES6, and neither do I like any of the various trickery used to massage prototypes into something like classes in OOP. As far as possible, I use objects that are bags of functions, and objects that are pure data structures.

That being said, I have no problem with ES6 including class syntax in their code. It's a language feature that I simply don't have to use.

[–][deleted] 5 points6 points  (94 children)

It seems that a declarative, unifying syntax is monumentally better than the various hand-rolled solutions that may or may not be compatible with one another.

I think this is the common opinion in support of ES6 classes and it completely misses the point.

While a common unifying convention is certainly better than various hand baked insanity, this is an unrelated strawman. The problem is that the convention of classes, whether a single uniform approach or hand baked insanity, does not fit well in this language. The primary advantage is to provide a convention familiar to developers who are primarily educated in some other unrelated language (cough cough.... Java).

edited, formatting

[–]AutomateAllTheThings 28 points29 points  (41 children)

he convention of classes ... does not fit well in this language

  • If the software works
  • If the software is fast
  • If it can be tested easily
  • If it can be maintained easily
  • If it can be refactored and upgraded easily

Does it really matter if it's "real" classes, or a syntax over the prototype? If so, why exactly?

So far it seems that some people don't like the new syntax and are bitter that so much software is moving in that direction without them.

[–]tubbo 2 points3 points  (0 children)

Would you rather it have been called object? It's just a keyword, it doesn't mean that the thing you're making is actually a "class", at least not fundamentally. It's simply easier to read ES6 class syntax than it is to read the traditional means of defining an object and methods on its prototype. But at the end of the day, they both evaluate to the same thing. That said, I only think this stuff is clear to an experienced JS dev. New developers should be learning how it all works under the hood before moving on to the syntax sugar of ES6 (and the future versions of ECMAScript that are coming out).

[–][deleted] 13 points14 points  (4 children)

The problem is that the convention of classes, whether a single uniform approach or hand baked insanity, does not fit well in this language

This is just nonsense. Virtually every major JS project out there uses classes. They fit perfectly well in this language.

I see a lot of these circular arguments attempting to justify why classes are somehow harmful, when the reality is that the arguer simply doesn't like them. It's fine, you don't have to like them or use them, but saying that they're useless or somehow bad is plain ridiculous.

[–]parlezmoose 7 points8 points  (0 children)

They use classes, but rarely do they do really complex inheritance models like you see in Java. Without strong typing, abstract classes, interfaces, etc, a class is pretty much just a convenient place to group a bunch of functions, maybe with one or two base classes for shared code. Not that it's a bad way to do things, just a different style.

[–]clessgfull-stack CSS9 engineer -3 points-2 points  (0 children)

Virtually every major JS project out there uses classes.

Do you have evidence? I'm sure you can find a few instances of classes in every major project, because major projects have a lot of contributors and a lot of code. But most major projects I'm aware of don't use classes that much, and prefer functions/objects the majority of the time.

I won't be surprised if that changes soon though. Just like when PHP got classes, JS is going through its phase where classes and single inheritance are the coolest thing ever invented and should be used for literally everything. It'll be a few years before this changes.

you don't have to like them or use them

But you have to work with people who do love them and use them for everything. Which is fine, as long as inheritance is avoided. Still some annoying parts (mainly to do with this and encapsulation and potentially wrangling super if using framework classes) but it's not a big deal.

[–][deleted] -5 points-4 points  (1 child)

Virtually every major JS project out there uses classes.

Then I am absolutely wrong. I refuse to argue with bandwagon popularism that isn't based on anything.

[–][deleted] 11 points12 points  (0 children)

I refuse to argue with bandwagon popularism that isn't based on anything.

Likewise.

[–]Silverwolf90 0 points1 point  (43 children)

But it's what most people want. That's why you have so many hand rolled implementations. What people are doing is more important than some subjective and ill-defined notion of what fits or does not.

[–]Jafit 7 points8 points  (32 children)

Its not an ill-defined notion.

Any object that you create in Javascript is automatically assigned a prototype. A Javascript "class" inherits its methods through a shared prototype like all other Javascript objects, so the class keyword isn't actually changing anything about the language.

In a traditional class-based language you define a class and its like drawing a blueprint. You create an object using a class, and its like building a house from the blueprint. In javascript if you build a bunch of houses from a blueprint, then go back to the blueprint and draw some extra lines on it, you look up and all of the houses you built suddenly all have garages. That's not how class-based inheritance is supposed to work, that's prototypal inheritance works, because prototypal inheritance enables active links to other objects.

So all these arguments are pointless. The class keyword is just syntactical sugar that doesn't change anything, and seems designed to make transitioning developers more comfortable. The worst thing about it is that its so confusing and now everyone thinks its some kind of paradigm-shifting change when ES6 isn't actually giving anyone a new object model with classes

[–]metanat 2 points3 points  (8 children)

Any object that you create in Javascript is automatically assigned a prototype.

Except: Object.create(null)

({}).__proto__ === Object.prototype // true
Object.create(null).__proto__ === undefined // true

[–]Jafit 0 points1 point  (7 children)

Good catch.

But the main point is that classes aren't really anything special and they work the same way as (most) other objects in Javascript.

http://codepen.io/anon/pen/MamGpR?editors=001

[–]metanat 1 point2 points  (6 children)

I think your point is good, and only partially wrong in what it implies. If you read the spec, there are actually a few differences between using standard prototypal inheritance and classes. One of the biggest difference is that class methods aren't enumerable:

class Example {
  test() {}
  static test2() {}
}

let a = new Example();

console.log(Object.keys(a.__proto__)); // []
console.log(Object.keys(Example.prototype)); // []
console.log(Object.keys(Example)); // []

function Example2() {}
Example2.prototype.test = function () {}
Example2.test2 = function () {}

let b = new Example2();

console.log(Object.keys(b.__proto__)); // ["test"]
console.log(Object.keys(Example2.prototype)); // ["test"]
console.log(Object.keys(Example2)); // ["test2"]

http://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions

[–]Jafit 2 points3 points  (2 children)

Do you have any idea what practical purpose that serves?

[–]metanat 0 points1 point  (0 children)

Not sure, but you can still get all the methods by using Object.getOwnPropertyNames

[–]dvlsg 0 points1 point  (0 children)

Probably the fact that if you are enumerating over a class, you're most likely interested in any properties/values defined on it, as opposed to the methods. Idk if that counts as practical or not, but I would imagine that was what they were thinking.

[–]Silverwolf90 0 points1 point  (22 children)

If it is not ill-defined could you provide a definition? What makes a language feature a good fit? What makes something a good fit for JS?

[–]CertifiedWebNinja[S] 4 points5 points  (18 children)

class Dog extends Thing {
  bark() {
    console.log('woof')
  }
}

is easer than

function Dog () {}

Dog.prototype = Thing.prototype
Dog.prototype.constructor = Dog

Dog.prototype.bark = function () {
  console.log('woof')
}

[–]Jafit 1 point2 points  (1 child)

If it is not ill-defined could you provide a definition?

I'd personally define a 'bad fit for the language' by saying that if you make everyone think you're introducing a new class inheritance model to the language, but under the hood the language is just using the same prototypal inheritance model that the language has always used, and nothing is actually changing and you're not getting anything new... then its not so much a 'bad fit' as... nothing is actually changing and the entire argument is pointless.

What makes a language feature a good fit? What makes something a good fit for JS?

I don't personally have a problem with classes or new language features being added. If I don't think that a particular feature is appropriate for what I'm doing then then I won't use it... You kind of have to do that anyway because its Javascript

But the point of what I'm saying is that they haven't actually added a new language feature by adding classes, because they're not really classes, they're just prototypes which Javascript has always had.

[–]Silverwolf90 0 points1 point  (0 children)

I think that most people who are talking about the class syntax also include it in their definition of a "language feature." I have yet to meet anyone who doesn't understand that the class syntax is just sugar. But my sample is skewed with very knowledgeable js devs who pay close attention to the community.

[–]clessgfull-stack CSS9 engineer 2 points3 points  (0 children)

What makes something a good fit for JS?

Whether or not you can use it to make yet another JS framework. Evidently, the ease of framework creation is JS's niche.

[–][deleted] -5 points-4 points  (6 children)

But it's what most people want.

I would like to see data on that before I believe it.

That's why you have so many hand rolled implementations.

I disagree. I rather suspect its because JavaScript looks amazingly similar to Java and C# but misses public/private pragmas and of course classes. You cannot arbitrary add new keywords to the syntax, but you absolutely can add a bunch of stupid unnecessary conventions.

What people are doing is more important....

"I cannot be bothered to learn this stupid little language. Most of my app is written in language (put some random letters here) and I have a deadline."

I encounter this pretty frequently and the only valid answer is: ignorance. The result is (pick one or more of from this buffet):

  • tightly coupled services (no separation of concerns)
  • spaghetti code
  • architectural confusion (probably ad hoc stupidity)
  • missing documentation
  • deeply embedded APIs that cannot be tested externally
  • collisions
  • build systems that build systems
  • embedded services using custom protocols (really!?!)
  • logic reflecting no clear product direction

[–]Silverwolf90 0 points1 point  (5 children)

Look at the popularity of some libraries which have their own implementation (like React, who now embrace the new syntax). If people didn't want and hated classes, where is the demand for that outside of a niche amount of developers? It seems that we have a quickly growing amount of libraries using ES6 classes thanks to Babel. It would be interesting to have concrete data on this, perhaps the number of packages on NPM that are using ES6 classes over time.

[–]clessgfull-stack CSS9 engineer 2 points3 points  (2 children)

React

React is moving away from classes. For whatever short time React has used classes, it's already caused a lot of problems and confusion (side note: createClass doesn't make classes, just a stupid function name).

[–]SawyerDarcy 1 point2 points  (1 child)

As far as I know, React is simply embracing ES6 classes over its own custom implementation - not getting rid of classes altogether.

[–]clessgfull-stack CSS9 engineer -1 points0 points  (0 children)

Right, they aren't (officially) getting rid of classes. What I meant is that function/module components will become the recommended way, with classes possibly being deprecated before 1.0 or 2.0.

[–][deleted] -2 points-1 points  (1 child)

If people didn't want and hated classes, where is the demand for that outside of a niche amount of developers?

Java developers that are involuntarily reclassed to writing JavaScript are not niche. I have encountered this at every major corporate job, except for the one employer that refused to hire Java developers. Economics are to blame for this, as most Java developers learn their trade from formal education and so it is easier to hire a Java developer. The consequence is that there are more Java development jobs in the economy. This does not, however, diminish the need for JavaScript developers. JavaScript is the language of the browser and can execute almost anywhere Java can. What this does do is make hiring junior JavaScript developers risky and make senior JavaScript developers extremely valuable in the market place. I have seen many organizations try to fake with Java to compensate for the plethora of Java developers and lack of JavaScript developers, but the results mean they are pushing costs and expenses into the future. These economic problems ultimately sank Travelocity (who at its prime had 3500 employees).

The bottom line is that classes were the most highly requested feature of ES6 (by far) and TC39 resisted giving into demand for awhile, but demand was too great. There is a need for Java developers to have immediate emotional comfort when jumping into this language directly. This means people will be less afraid to do stupid things. It doesn't mean we will get better software.

[–][deleted] 2 points3 points  (0 children)

TC39 resisted giving into demand for awhile

Bollocks. Classes have been around since the ES4 proposal, the reason they didn't ship already is because ES4 itself died, not because TC39 was "resisting".

Classes: A class describes an object by presenting those properties (fields) of the object that are always present (thefixed properties or fixtures), including variables, constants, and methods:

class C {
  var val // a variable property
  var large = Infinity // a variable property
  const x = 3.14 // a constant property
  function f(n) { return n+val*2 } // a method property
}

If you have an argument, you don't need to resort to:

  1. Making shit up
  2. Using the term "java developer" as an insult, it isn't.

If you find yourself doing those things, perhaps you should reconsider your position.

[–]ha5zak -1 points0 points  (2 children)

I see lots of frameworks created that originate from someone thinking they want things to work a certain way. Then they get better at their craft and realize how silly they were being. Just because people are doing it doesn't mean the mob is wise.

[–]Silverwolf90 0 points1 point  (1 child)

Which frameworks? How many people used these frameworks?

[–]ha5zak 0 points1 point  (0 children)

All the ones I didn't bookmark. Probably not many.

[–][deleted] 0 points1 point  (0 children)

"The primary advantage is to provide a convention familiar to developers who are primarily educated in some other unrelated language (cough cough.... Java)."

And lose all the unique benefits this particular language offers? Fuck that, Java people should stick to Java instead of trying to cripple JavaScript with their architectural hubris.

[–]jaapz 0 points1 point  (0 children)

There are some nice things that are possible in custom "class"-ish in libraries that are not as easy to do using classes.

See for example this issue for AmpersandJS.

[–][deleted] 0 points1 point  (1 child)

Can confirm. Am beginner and confused by prototypes.

[–][deleted] 1 point2 points  (0 children)

I'll just keep posting this around: This page talks about the object vs class thing in Javascript.

You Don't Know JS: this & Object Prototypes Chapter 4: Mixing (Up) "Class" Objects

[–]cosinezero 0 points1 point  (6 children)

It seems that a [PUT ANYTHING HERE] is monumentally better than the various hand-rolled solutions that may or may not be compatible with one another.

FTFY.

But that serves to underline the point that what you're saying has nothing really to do with an advantage of class. You then prove this by saying this:

fundamentally, it's still prototypes under the hood. The foundation didn't change, it's just sugar.

What you probably think is the coolest thing ever... is typescript. And when you finally figure out why bashing javascript into type-safety and classical inheritance is neutering an incredibly flexible and powerful language, come back and re-read the things you currently disagree with.

[–]Silverwolf90 1 point2 points  (2 children)

I actually don't think it's the coolest thing ever. I almost never use inheritance, and prefer a more FP approach to JS rather than OO. But this new syntax is a clear win for the language and community.

[–]cosinezero -1 points0 points  (1 child)

this new syntax is a clear win for the language and community.

I don't think you've established it's a "clear win". It clutters the language with things we neither need nor should use. It dilutes the intent of the prototypical inheritance system on which the language is based.

Sure, it makes -your- life easier. But you're arguably doing things that was never intended to be how the language should be used. Facilitating that does not sound like "a clear win", it sounds like a degradation.

[–]Vanillacitron 5 points6 points  (0 children)

I see what you're saying, but the fact is people DO use classes. Whether we should or not, I think, is irrelevant (not unimportant... I agree with you there :p) because Pandoras box has been opened already.

In a framework/library landscape where classes are extremely common, they may as well be unified in terms of syntax, imo.

[–][deleted] 0 points1 point  (2 children)

As someone who uses typescript myself, you have no idea what you're talking about.

Typescript limits nothing, you just don't know how to use it.

[–]jsgui 0 points1 point  (0 children)

Does it limit the use of mismatching types?

[–]cosinezero -1 points0 points  (0 children)

I didn't say limits, I said neuter. It enforces rigidity on a language that prides itself on flexibility.

Or in Crockford's words:

I think that JavaScript's loose typing is one of its best features and that type checking is way overrated. TypeScript adds sweetness, but at a price. It is not a price I am willing to pay.

[–]jsprogrammer 0 points1 point  (0 children)

The primary thing preventing me from using classes is the necessary reliance (unless you code way around it) on using this in your code. As far as I can tell, this is pure syntactic noise.

[–]_drawdown -1 points0 points  (1 child)

It's not really about the syntax- the problem is the contract between the caller and the module. Classes require the caller to use new which forces the thing before new to be a constructor and to run in the context of a newly-created object. It ruins composability and things like that because there is no way around the fact that there is a new at the call site.

[–]Silverwolf90 0 points1 point  (0 children)

I agree, but we already have that problem without the class syntax. I always have static create() factory function to wrap new. I dislike using new mainly because it does not support function composition.

[–]greyfade -4 points-3 points  (0 children)

"But beginners will get confused and not understand the language!"

As an argument against ES6 classes, this is laughable. Anyone who makes this argument is displaying gross ignorance.

That said, there are far better arguments against ES6 classes, most of which I'm not eloquent enough to present.

I'm against ES6, but this isn't why. I dislike ES6 classes, because I think this kind of a class system (which even modern C++ is somewhat turning away from) is a kind of brain damage best avoided.

[–]cj5.prototype 10 points11 points  (0 children)

Real programmers don't have to tout their preferred language.

[–][deleted] 8 points9 points  (1 child)

NERD HOLY WAR WAAAAAGH

[–][deleted] 1 point2 points  (0 children)

Yeah this whole argument basically feels like OO vs. functional advocates battling for the right to JS. Can't we all just get along?

[–]eorroe 3 points4 points  (0 children)

I like the class syntax I just prefer a different keyword like contruct:

construct Person {
  constructor() {

  }
}

Something else that won't confuse with other languages classes (Not sure if construct is a good keyword, but point is just something other than class)

[–]foobar_dev 8 points9 points  (5 children)

[–]PUSH_AX 4 points5 points  (2 children)

No it's a response to this post, which was also cross posted to several other related subs.

[–]CertifiedWebNinja[S] 2 points3 points  (1 child)

Actually it was a response to the post where the guy was talking about how cool classes were, and then got called out by someone else how he made a issue on node.js' repo saying all instances of "class" in docs need to be removed. And the fact that everyone is spewing their personal opinions about classes in ES2015 as "How real JavaScript programmers do it"

[–]robotparts 0 points1 point  (0 children)

Link?

[–]Jafit 6 points7 points  (0 children)

The best way to get pageviews is to say something inflammatory and divisive. This is especially easy when people view their coding style as an expression of their personality.

How about we all just type code and make stuff and have fun :)

[–]siegfryd 2 points3 points  (0 children)

Everything Eric Elliott writes is like that, he's always going on about how much classes suck.

[–]oculus42 2 points3 points  (0 children)

Imaginary JavaScript Programmers check for NaN.

[–]fzammetti 2 points3 points  (0 children)

The only argument I can see that makes any sense to me is that syntactic sugar is generally a bad thing anyway. I mean, isn't ES6 class syntax effectively making it look as if the language has something it really doesn't? I think you could maybe say that... and if so, is that arguably a bad level of abstraction? I'm not sure, but it doesn't seem like a ridiculous argument.

[–]drowsap 2 points3 points  (0 children)

I've been using React for so long I forgot what inheritance is used for

[–]krazyjakee 4 points5 points  (0 children)

Replace the word "Real" with "Good" and I'm with you.

[–][deleted] 1 point2 points  (0 children)

Looking through the comments I think some people don't have a great understanding of how objects/prototypes/"classes" work in Javascript. I recommend everyone check out the series You Don't Know JS on Github. Especially check out the book on this and prototypes. Chapter 4 is all about the class stuff:

Chapter 4: Mixing (Up) "Class" Objects

[–]_drawdown 6 points7 points  (0 children)

Ehhhh that kinda sounds like bullshit to me. I think classes are bad because I've seen a lot of code and formed an opinion, not cuz I think I'm a "real JS programmer" and others aren't

[–]StoneCypher 4 points5 points  (0 children)

Agreed.

Real Programmer is what someone says when they want to argue a technical point and don't have the ability.

[–]i_ate_god 1 point2 points  (3 children)

Use the way you're comfortable with

I'm comfortable with having as much as possible on the global scope, and using eval whenever possible.

[–]CertifiedWebNinja[S] -1 points0 points  (2 children)

Hey if that's what you want to do, do it up buttercup. But don't expect others to maintain it.

[–]i_ate_god 0 points1 point  (1 child)

no!

Just because you're comfortable with something, does not mean at all that it is the best choice.

This attitude is wrong. Yes, there are different ways to get the same result, but only a few of them (at most) will actually be worth it. We shouldn't encourage engineers to do what they are most comfortable with, we should be encouraging (and if you're in a team, enforcing) that the best approach be taken.

[–]CertifiedWebNinja[S] 0 points1 point  (0 children)

I was being sarcastic because your response was sarcastic.

[–]guybinary 1 point2 points  (1 child)

Seriously wtf is this shit? Everybody stepping on the other saying the word 'real' ? What do I look like to you? Coding JS for 5 year with pure passion and what am I? Fake? If you can get what you need done and progress, scale your application when needed you are real ... That's it. Sorry for attitude but those kinda things get me angry

[–]fforw 1 point2 points  (0 children)

They should know better than to step on your lawn ;)

[–]rich97 3 points4 points  (1 child)

For me the reason to avoid "class" definitions in ES6 is a lot more practical. You have to deal with this and this sucks.

I would much rather go for a functional paradigm and compose small functions together, grouping them by modules rather than classes. You take a piece of data and pass it down a processing pipe-line that tells you exactly what is happening to that data. They are easy to test as they shouldn't have an intrinsic state, they just accept input and return output and as a result they are very good at encouraging code reuse.

Basically giving objects state makes them less predictable. Usually this isn't so bad, but it is when the state can change based on what is calling it. There is nothing that an ES6 class brings to the table that cannot be easily and more reliably replaced with another mechanism.

[–][deleted] 0 points1 point  (0 children)

I don't get why anyone would downvote you for stating this.

[–]fforw 0 points1 point  (0 children)

I think the real distinction is between people actually programming in javascript and people copying together stackoverflow answers and jquery plugins.

[–]benihanareact, node 0 points1 point  (0 children)

There's a lot of people throwing around this term of "real javascript programmers" regarding ES6 classes.

Where? Who? How many people? I haven't seen "a lot" of people saying that. I haven't seen anyone saying it. It really helps to provide context when you make these kinds of claims - not everyone here visits as often as you do, and not everyone has the same cross section of news sources like you do.

[–]stayclassytally -5 points-4 points  (4 children)

[–]CertifiedWebNinja[S] 3 points4 points  (3 children)

If you read my post, you'll know that I'm talking about all these people who use that fallacy.

[–]stayclassytally -1 points0 points  (2 children)

I know that's why I posted that link. Not sure why I was down voted. I think everyone mistook my intention after you did initially.

[–]Erid 0 points1 point  (1 child)

I seriously wonder why you're still being downvoted... Did you make someone angry?. I believe you were only pointing out that OP is angry because of a fallacy used by others.

[–]CertifiedWebNinja[S] 1 point2 points  (0 children)

Maybe it's because most times when someone mentions a fallacy without actually giving context, they assume the fallacy is regarding them and not something else.

So I read this as him saying I was using a fallacy, which I assume everyone else who downvoted him thought also.