Home are es6 classes just syntactic sugar for the prototypal pattern in javascript?
Reply: 5

are es6 classes just syntactic sugar for the prototypal pattern in javascript?

pushplaybang Published in 2016-04-05 07:24:20Z

After playing with ES6 I've really started to like the new syntax and features available, but I do have a question about classes.

are the new ES6 classes just syntactic sugar for the old prototypal pattern? or is there more going on here behind the scenes? ie:

class Thing {
   //... classy stuff

vs :

var Thing = function() {
  // ... setup stuff

Thing.prototype.doStuff = function() {}; // etc
alex Reply to 2016-04-05 07:25:24Z

Are the new ES6 classes just syntactic sugar for the old prototypal pattern?

Yes, they are simply a convenience syntax, the semantics are identical.

JavaScript classes are introduced in ECMAScript 6 and are syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax is not introducing a new object-oriented inheritance model to JavaScript. JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance.


The following short code example proves it too.

class Thing {
   someFunc() {}

console.log("someFunc" in Thing.prototype); // true
Tresdin Reply to 2016-04-05 08:33:40Z

Yes. But they're more strict.

There are two major differences in your examples.

First of all, with the class syntax, you can't initialize an instance without new keyword.

class Thing{}
Thing() //Uncaught TypeError: Class constructor Thing cannot be invoked without 'new'

var Thing = function() {
  if(!(this instanceof Thing)){
     return new Thing();
Thing(); //works

The second one is, classes defined with class syntax are block scoped. It's similar to defining variables with let keyword.

class Thing{}
class Thing{} //Uncaught SyntaxError: Identifier 'Thing' has already been declared

    class Thing{}
console.log(Thing); //Uncaught ReferenceError: Thing is not defined


As @zeroflagL mentioned in his comment, class declarations are also not hoisted.

console.log(Thing) //Uncaught ReferenceError: Thing is not defined
class Thing{}
Redu Reply to 2016-04-05 07:37:03Z

They are totally syntactical sugar. What's new about prototypical inheritance in ES6 is the redefinition of the __proto__ property of the objects. __proto__ is legal now and that's how array subclassing has become possible with JS.

Ted Nyberg
Ted Nyberg Reply to 2016-04-05 08:01:11Z

Short answer: yes. :) But there's a lot more to it - the "transpile-time" type checking is something entirely different than what you'd be used to using vanilla ECMA/JavaScript.

Edit: Sorry, I totally misunderstood the OP's question, for some reason I interpreted this question to be about TypeScript. :/ Perhaps I should remove this answer?

traktor53 Reply to 2017-12-06 10:32:24Z

Yes, perhaps, but some of the syntactic sugar has teeth.

Declaring a class creates a function object that is the constructor for the class, using the code provided for constructor within the class body, and for named classes, with the same name as the class.

The class constructor function has a normal prototype object from which class instances inherit properties in normal JavaScript fashion. Instance methods defined within the class body are added to this prototype.

ES6 does not provide a means to declare class instance default property values (i.e. values which are not methods) within the class body to be stored on the prototype and inherited. To initialize instance value you can either set them as local, non inherited properties within the constructor, or manually add them to the class constructor's prototype object outside the class definition in the same fashion as for ordinary constructor functions. (I am not arguing the merits or otherwise of setting up inherited properties for JavaScript classes).

Static methods declared within the class body are added as properties of the class constructor function. Avoid using static class method names that compete with standard function properties and methods inherited from Function.prototype such as call, apply or length.

Less sugary is that class declarations and methods are always executed in strict mode, and a feature that gets little attention: the .prototype property of class constructor functions is read only: you can't set it to some other object you've created for some special purpose.

Some interesting stuff happens when you extend a class:

  • the prototype object property of the extended class constructor is automatically prototyped on the prototype object of the class being extended. This is not particularly new and the effect can be duplicated using Object.create.

  • the extended class constructor function (object) is automatically prototyped on the constructor function of the class being extended, not Function. While it may be possible to replicate the effect on an ordinary constructor function using Object.setPrototypeOf or even childClass.__proto__ = parentClass, this would be an extremely unusual coding practice and is often advised against in JavaScript documentation.

There are other differences such as class objects not being hoisted in the manner of named functions declared using the function keyword.

I believe it could be naive to think that Class declarations and expressions will remain unaltered in all future versions of ECMA Script and it will be interesting to see if and when developments occur. Arguably it has become a fad to associate "syntactical sugar" with classes introduced in ES6 (ECMA-262 standard version 6) but personally I try to avoid repeating it.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.394256 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO