I have many question about ES6 classes.
Since i understand how to use function and WebComponent, React & so. I didn't see many benefit using it.
I wonder what's the benefit of using classes. I read that public/private/static will be part of ES7. So i see no point using it currently.
Moreover, will class be a concept of OOP or it still be a 'javascript object concept'? Does it mean i can't modify it using .prototype
? Or is it just the same object but 2 different way to declare it.
Is there a benefits about the speed? Maybe it's easier to maintain/understand if you have a big application like Big Java app ?
tl;dr : The question is in the title.
INFORMATION : I notice people still come to see this q/a which is more than 2 years ago now. Answer is still accurate, but remember javascript has evolve 'a bit' since.
ES6 classes are syntactic sugar for the prototypical class system we use today. They make your code more concise and self-documenting, which is reason enough to use them (in my opinion).
Using Babel to transpile this ES6 class:
will give you something like:
The second version isn't much more complicated, it is more code to maintain. When you get inheritance involved, those patterns become even more complicated.
Because the classes compile down to the same prototypical patterns we've been using, you can do the same prototype manipulation on them. That includes adding methods and the like at runtime, accessing methods on
Foo.prototype.getBar
, etc.There is some basic support for privacy in ES6 today, although it's based on not exporting the objects you don't want accessible. For example, you can:
and
BAR_NAME
will not be available for other modules to reference directly.A lot of libraries have tried to support or solve this, like Backbone with their
extends
helper that takes an unvalidated hash of method-like functions and properties, but there's no consist system for exposing prototypical inheritance that doesn't involve mucking around with the prototype.As JS code becomes more complicated and codebases larger, we've started to evolve a lot of patterns to handle things like inheritance and modules. The IIFE used to create a private scope for modules has a lot of braces and parens; missing one of those can result in a valid script that does something entirely different (skipping the semicolon after a module can pass the next module to it as a parameter, which is rarely good).
tl;dr: it's sugar for what we already do and makes your intent clear in code.
It's (almost) entirely up to you whether you do. The new
class
stuff is mostly just syntactic sugar. (But, you know, the good kind of sugar.) There's nothing in ES2015-ES2018 thatclass
can do that you can't do with constructor functions andReflect.construct
(including subclassingError
andArray
¹). (There is likely to be something in ES2019 or ES2020 that you can do withclass
that you can't do otherwise: private fields and private methods.)It's the same prototypical inheritance we've always had, just with cleaner and more convenient syntax if you like using constructor functions (
new Foo
, etc.). (Particularly in the case of deriving fromArray
orError
, which you couldn't do in ES5 and earlier. You can now withReflect.construct
[spec, MDN], but not with the old ES5-style.)No, you can still modify the
prototype
object on the class's constructor once you've created the class. E.g., this is perfectly legal:By providing a specific idiom for this, I suppose it's possible that the engine may be able to do a better job optimizing. But they're awfully good at optimizing already, I wouldn't expect a significant difference.
If you don't like using constructor functions (
new Foo
), don't use the new syntax, it doesn't do anything for you. If you do, then reasons you might choose to:The syntax is simpler and less error-prone.
It's much easier (and again, less error-prone) to set up inheritance hierarchies using the new syntax than with the old.
class
defends you from the common error of failing to usenew
with the constructor function (by having the constructor throw an exception ifthis
isn't a valid object for the constructor).Calling the parent prototype's version of a method is much simpler with the new syntax than the old (
super.method()
instead ofParentConstructor.prototype.method.call(this)
orObject.getPrototypeOf(Object.getPrototypeOf(this)).method.call(this)
).Here's a syntax comparison for a hierarchy:
Example:
vs.
Live Example:
As you can see, lots of repeated and verbose stuff there which is easy to get wrong and boring to retype (which is why I wrote a script to do it, back in the day).
¹ "There's nothing in ES2015-ES2018 that
class
can do that you can't do with constructor functions andReflect.construct
(including subclassingError
andArray
)"Example: