Skip to content Skip to sidebar Skip to footer

Are The Es6 Classes Really Semantic Sugar?

If they are just semantic sugar how can I get the same result of the following es6 scripts in es5? class MyFunc extends Function{} new MyFunc('alert('hi guys')')() and class MyArr

Solution 1:

No, they are only mostly syntactic sugar. They can do all the things that the class pattern did in ES5, but also more than that.

The details of how objects are instantiated, especially in subclasses, was overhauled, and now allows to subclass the builtins like Function and Array as in your question. This was not possible in ES5. For details, have a look at What is "new.target"?, What does super() actually do in constructor function? and What do subclass constructor objects inherit from?.

Solution 2:

I'm not sure about es5, but it is possible to simulate es6 classes without using the class syntax, using other es6 features instead.

For example, your example

classMyFuncextendsFunction{}
newMyFunc('alert("hi guys")')()

Can be simulated using old style classes and Reflect.construct as follows

functionMyFunc(...args) {returnReflect.construct(Function, args, new.target);}
newMyFunc('alert("hi guys")')()

Reflect.construct does what the super() call in a real subclass constructor would do, which is all you need for the example posted. If you want to properly inherit all the properties and static methods, you need to additionally set the prototypes like this

functionMyFunc(...args) {returnReflect.construct(Function, args, new.target);}
Object.setPrototypeOf(MyFunc, Function);
Object.setPrototypeOf(MyFunc.prototype, Function.prototype);
newMyFunc('alert("hi guys")')()

This also works for the array example

functionMyArr(...args) {returnReflect.construct(Array, args, new.target);}
Object.setPrototypeOf(MyArr, Array);
Object.setPrototypeOf(MyArr.prototype, Array.prototype);
var myarr = newMyArr(1,2,3,4)
myarr[2] = "a value"
myarr.push("an other value")

The first set prototype call is only required to inherit static properties like Array.from. If you don't care about those, you can get away with only setting up the prototype of the prototype object, in which case you don't need Object.setPrototypeOf at all. You can instead use Object.create as follows:

functionMyArr(...args) {returnReflect.construct(Array, args, new.target);}
MyArr.prototype = Object.create(Array.prototype);
MyArr.prototype.constructor = MyArr;
var myarr = newMyArr(1,2,3,4)
myarr[2] = "a value"
myarr.push("an other value")

For more details, see this post.

Solution 3:

It's sugar because it does in background what you can do with prototype.

You have all the explanations here :

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

ps: sugar does not mean bad for me, it's clearly easier to read, but some does not like.

For the array you can do :

let arr = newArray(1,2,3,4);
arr[2] = "a value";
arr.push("an other value");

No ?

& I had to say that people do not clearly understand JS. When you 'extend' in es6 you do not create an independent type .. that is the mistake the sugar do in your mind .

Just try this code:

classMyArrextendsArray{}
let myarr = newMyArr(1,2,3,4);
myarr[2] = "a value";
myarr.push("an other value");
console.log("ah");

Array.prototype.push = function () {
  console.log('NAH');
}

let a = [];
a.push("an other value");
myarr.push("an other value");

If you change Array prototype methode you will change it in extended Class too by reference.

Post a Comment for "Are The Es6 Classes Really Semantic Sugar?"