Javascript 无法在ES6类定义中定义原型属性

Javascript 无法在ES6类定义中定义原型属性,javascript,ecmascript-6,babeljs,Javascript,Ecmascript 6,Babeljs,我在尝试ES6语法,发现我无法在类定义中定义原型属性或实例属性,为什么禁止它 我以前使用的是MyClass.prototype.prop=1,请按如下所示使用babel编译器尝试ES7,但仍然无法定义prototype属性 class MyClass{ prop=1; static sProp=1; } 我不认为定义实例属性有任何危险,在我自己的浏览器游戏中有两种情况需要原型属性: class MyClass { static _dummy = MyClass.prototyp

我在尝试ES6语法,发现我无法在类定义中定义原型属性或实例属性,为什么禁止它

我以前使用的是
MyClass.prototype.prop=1
,请按如下所示使用babel编译器尝试ES7,但仍然无法定义prototype属性

class MyClass{
  prop=1;
  static sProp=1;
}
我不认为定义实例属性有任何危险,在我自己的浏览器游戏中有两种情况需要原型属性:

class MyClass {
    static _dummy = MyClass.prototype.prop1 = <expression1>
    static _dummy = MyClass.prototype.prop2 = <expression2>
    // or
    static _dummy = this.prototype.prop2 = <expression2>
}
  • 子类实例需要从基类继承相同的属性值:

    var Building=function(){...}
    Building.prototype.sight=350;
    TerranBuilding.CommandCenter=...(CommandCenter extends Building)
    TerranBuilding.Barracks=...(Barracks extends Building)
    
  • 因此,指挥中心和兵营的建筑景观将与350相同。

    new CommandCenter().sight===new Barracks().sight//All buildings have same sight
    
  • 缓冲区效果覆盖原始属性并删除缓冲区

    Marine.prototype.speed=20
    var unit=new Marine()
    unit.speed===20//get unit.__proto__.speed 20
    unit.speed=5//Buffer:slow down speed, unit.speed will override unit.__proto__.speed
    delete unit.speed//Remove buffer
    unit.speed===20//true, speed restore
    

  • 因此,我认为应该增加一种设置prototype属性的方法,而不是完全禁止它,或者您可以给出一些其他解决方案来处理上述两种情况吗?

    这两种方法都不会出现在类prototype上

    class Foo{bar=1;}
    语法将为分配一个值,使用
    this.bar
    访问

    class Foo{static bar=1;}
    语法将为分配一个值,通过
    Foo.bar
    访问

    在这种情况下,没有太多理由使用原型。这只会使实际拥有该属性的人变得复杂,在几个不同的类中分配一个数字只会产生很少的开销


    我建议使用class instance属性,只要在需要的地方使用this.sight即可。

    我认为另一个答案没有抓住这个问题的重点。继承的全部意义在于,您可以决定何时何地覆盖某些内容。如果有人认为这是一种开销,你为什么要使用OOP语言呢

    我不知道为什么它是“禁止”的,但我可以分享一些想法。 我很确定没有办法用“class”关键字定义原型属性。任何定义都将安装在“hasOwnProperty”上。一个巨大的挫折是,在构造函数中,无法让任何父构造函数与重写的属性交互

    class MyClass{
      prop=1;
      static sProp=1;
    }
    
    从推理的角度来看,它实际上被另一个特性所排除:您可以使用表达式这个指定属性

    class A extends B { sight = this.getSight() * 3 }
    
    当表达式失效时,它要么与实例一起运行(使用构造函数创建),要么在创建原型时在类声明处运行

    访问器和方法没有这个问题。它们在原型定义时定义,并在实例运行时调用

    使用带“=”的表达式定义的属性是表达式的返回值。它在定义后立即被免除-应该是实例创建时间,否则这将不可用

    所以这与模式无关。它是关于表达式或继承的。我当然更喜欢继承,当你可以将表达式直接写入构造函数时,表达式是毫无意义的

    class A extends B { constructor() { this.sight = this.getSight() * 3 } 
    
    使用装饰器是一项很好的工作。您始终可以使用javascript对原型执行某些操作:

    @B({sight:2}) class A {};
    
    装饰师B是:

    function(option) {return function(clazz) {clazz.prototype.sight = option.sight; return clazz}}
    

    向类主体内的原型添加属性的最简单方法是使用原型赋值作为虚拟静态属性的“值”:

    class MyClass {
        static _dummy = MyClass.prototype.prop1 = <expression1>
        static _dummy = MyClass.prototype.prop2 = <expression2>
        // or
        static _dummy = this.prototype.prop2 = <expression2>
    }
    
    class-MyClass{
    静态_dummy=MyClass.prototype.prop1=
    静态_dummy=MyClass.prototype.prop2=
    //或
    静态_dummy=this.prototype.prop2=
    }
    
    (它在没有括号的情况下工作,因为
    =
    是右关联的,并且可以为每个原型分配重复使用相同的虚拟属性)


    如果您想对值进行更有趣的(多行)计算,则初始值设定项可以是立即执行的函数表达式,在这种情况下,您基本上已经创建了,并且可以将原型和类对象的所有初始化都放在其中。

    一个有效的用例是OP确实希望继承属性,你的建议没用。也就是说,他们可以在对象级别重写它,然后通过执行
    delete obj.shadowingProperty
    可以改用getter吗
    class MyClass{get prop(){return 1;}}
    @JuanMendes每种单元类型都定义了许多属性,例如大小、hp、mp和损坏,要编写get/set,所有这些属性都会让人筋疲力尽;对于我的案例2,由于缓冲区效应,我有时需要覆盖默认属性值,并且可以通过delete unit.prop删除该缓冲区以禁止覆盖默认单元。proto.prop,您的get/set不能简单地支持这一点。在原型上有原子值通常被认为是一种反模式。原型主要用于方法。在实例上保留原子值。这不是ES7,这是一个建议。@torazaburo我不知道为什么它会是一个反模式。原型适用于对象实例共享的任何对象。在我看来,危险在于原型上有可变对象,因为您可以对其进行变异,而这种变化将反映在所有实例上。如果原型上有一个基元,并且执行了
    this.prim=5
    ,则会在对象本身上设置一个值,并且不会影响原型上的值。请发布一个链接,解释为什么“这通常被认为是一种反模式”
    class MyClass {
       constructor() {
        MyClass.prototype.prop2 = "Marry";
      }
    }
    
    const mc = new MyClass()
    mc.__proto__ // { prop2: "Marry" }