es6类真的是语义糖吗?

时间:2017-12-30 18:43:05

标签: javascript ecmascript-6 es6-class

如果它们只是语义糖,我怎样才能在es5中得到以下es6脚本的相同结果?

class MyFunc extends Function{}
new MyFunc('alert("hi guys")')()

class MyArr extends Array{}
var myarr = new MyArr(1,2,3,4)
myarr[2] = "a value"
myarr.push("an other value")

3 个答案:

答案 0 :(得分:4)

不,他们只是主要是语法糖。他们可以完成类模式在ES5中所做的所有事情,但也可以做更多。

对象的实例化细节,特别是在子类中的细节进行了彻底检查,现在允许像你的问题那样继承像FunctionArray这样的内置类。这在ES5中是不可能的。有关详细信息,请查看What is "new.target"?What does super() actually do in constructor function?What do subclass constructor objects inherit from?

答案 1 :(得分:1)

我不确定es5,但是可以在不使用class语法的情况下模拟es6类,而是使用其他es6功能。

例如,您的示例

class MyFunc extends Function{}
new MyFunc('alert("hi guys")')()

可以使用旧样式类和Reflect.construct进行模拟,如下所示

function MyFunc(...args) {return Reflect.construct(Function, args, new.target);}
new MyFunc('alert("hi guys")')()

Reflect.construct执行真正的子类构造函数中的super()调用所做的事情,这就是发布的示例所需的全部内容。如果要正确继承所有属性和静态方法,还需要另外设置这样的原型

function MyFunc(...args) {return Reflect.construct(Function, args, new.target);}
Object.setPrototypeOf(MyFunc, Function);
Object.setPrototypeOf(MyFunc.prototype, Function.prototype);
new MyFunc('alert("hi guys")')()

这也适用于数组示例

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

第一组原型调用只需要继承静态属性,如Array.from。如果你不关心那些,你可以只设置原型对象的原型,在这种情况下你根本不需要Object.setPrototypeOf。您可以改为使用Object.create,如下所示:

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

有关详细信息,请see this post.

答案 2 :(得分:-1)

它是糖,因为它在背景中可以用原型做。

你在这里有所有解释:

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

ps:ps对我来说并不意味着什么,它显然更容易阅读,但有些人不喜欢。

对于您可以执行的阵列:

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

不是吗?

&安培;我不得不说人们不清楚JS。 当你在es6中“延伸”时,你不会创建一个独立的类型..这是糖在你脑海中的错误。

试试这段代码:

class MyArr extends Array{}
let myarr = new MyArr(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");

如果您更改了Array原型方法,您也可以通过引用在扩展类中更改它。