ES6类变量的替代品

目前在ES5中,我们中的很多人在框架中使用以下模式来创建类和类变量,这很简单:

// ES 5
FrameWork.Class({

    variable: 'string',
    variable2: true,

    init: function(){

    },

    addItem: function(){

    }

});

在ES6中,你可以在本地创建类,但是没有选择类变量的选项:

// ES6
class MyClass {
    const MY_CONST = 'string'; // <-- this is not possible in ES6
    constructor(){
        this.MY_CONST;
    }
}

可悲的是,上述方法无效,因为类只能包含方法。

我明白我可以在constructor this.myVar = true ,但我不想' this.myVar = true '我的构造函数,尤其是当我有更大类的20-30个参数时。

我正在想办法解决这个问题,但还没有找到任何好的方法。 (例如:创建一个ClassConfig处理程序,并传递一个parameter对象,该parameter对象与该类分开声明,然后该处理程序将附加到该类上,我也想着WeakMaps也以某种方式进行集成。)

你有什么样的想法来处理这种情况?


ES维基中针对ES6中提案的注释(最小类)注意:

有(有意)没有直接声明的方式来定义原型数据属性(除方法)类属性或实例属性

类属性和原型数据属性需要在声明之外创建。

在类定义中指定的属性被赋予与在对象字面值中出现的属性相同的属性。

这意味着你所要求的是被考虑的,并且明确地反对。

但为什么?

好问题。 TC39的优秀人员需要类声明来声明和定义类的功能。 不是它的成员。 ES6类声明为其用户定义其合同。

记住,类定义定义了原型方法 - 在原型上定义变量通常不是你所做的。 你当然可以使用:

constructor(){
    this.foo = bar
}

在你建议的构造函数中。 另请参阅共识摘要。

ES7及更高版本

ES7的新建议正在开发中,它允许通过类声明和表达式来实现更简洁的实例变量 - https://esdiscuss.org/topic/es7-property-initializers


为了增加Benjamin的答案 - 类变量是可能的,但是你不会使用prototype来设置它们。

对于一个真正的类变量,你需要做如下的事情:

class MyClass {}
MyClass.foo = 'bar';

在类方法中,该变量可以作为this.constructor.foo (或MyClass.foo )访问。

这些类属性通常不能从类实例中访问。 即MyClass.foo给出'bar'但是new MyClass().fooundefined

如果你想从一个实例访问你的类变量,你必须另外定义一个getter:

class MyClass {
    get foo() {
        return this.constructor.foo;
    }
}

MyClass.foo = 'bar';

我只用Traceur测试过,但我相信它在标准实现中的工作原理是一样的。

JavaScript并没有真正的类。 即使在ES6中,我们也在寻找基于对象或原型的语言,而不是基于类的语言。 在任何function X () {}X.prototype.constructor指向X 当在X上使用new运算符时,会创建一个继承X.prototype的新对象。 从那里查找新对象(包括constructor )中的任何未定义的属性。 我们可以将其视为生成对象和类属性。


在你的例子中:

class MyClass {
    const MY_CONST = 'string';
    constructor(){
        this.MY_CONST;
    }
}

由于MY_CONST是简单的https://developer.mozilla.org/en-US/docs/Glossary/Primitive,我们可以这样做:

class MyClass {
    static get MY_CONST() {
        return 'string';
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass

// alert: string ; true

但是,如果MY_CONSTstatic get MY_CONST() {return ['string'];}引用类型,请static get MY_CONST() {return ['string'];}警报输出是字符串,false。 在这种情况下, delete操作员可以做到这一点:

class MyClass {
    static get MY_CONST() {
        delete MyClass.MY_CONST;
        return MyClass.MY_CONST = 'string';
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass

// alert: string ; true

最后,对于不是const类变量:

class MyClass {
    static get MY_CONST() {
        delete MyClass.MY_CONST;
        return MyClass.MY_CONST = 'string';
    }
    static set U_YIN_YANG(value) {
      delete MyClass.MY_CONST;
      MyClass.MY_CONST = value;
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    set MY_CONST(value) {
        this.constructor.MY_CONST = value;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass
// alert: string, true
MyClass.MY_CONST = ['string, 42']
alert(MyClass.MY_CONST);
new MyClass
// alert: string, 42 ; true
链接地址: http://www.djcxy.com/p/52193.html

上一篇: ES6 class variable alternatives

下一篇: Pass a JavaScript function as parameter