Are The Es6 Classes Really Semantic Sugar?
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?"