如何在 ES6 中执行严格的 class 模式

How to enforce a strict class schema in ES6

我是 es6 的新手,想知道这种方法是否 OK.I 不希望有人在我的对象上设置我不想要的属性。

export default class User {

static getMembers() {
    return ['username','email','fullname','birthdate'];
}

constructor(props) {
    Object.keys(props).forEach((p)=>{
        if (User.getMembers().includes(p)) this[p]=props[p]
    });
    Object.defineProperty(this,"username",{writable:false});
    Object.defineProperty(this,"email",{writable:false});
}

还有其他方法吗?

使用如图所示的代码,您无法为 usernameemail 设置任何值。它们将始终为 undefined,因为您已将它们设置为只读且未为其分配值。您也没有做任何事情来阻止代码访问这些对象之一设置完全任意 属性:

let u = new User();
x.anythingIWant = 42;

如果你想阻止代码向对象添加属性,你可以使用 Object.seal(参考:MDN, spec)来实现,这会阻止添加新属性并且无法重新-定义现有属性。所以:

export default class User {
    constructor() {
        // ...create your desired properties

        // Seal the object
        Object.seal(this);
    }
}

如果您还想将 usernameemail 设置为只读,您还需要包括您拥有的 Object.defineProperty 调用(beforeObject.seal)。只需确保先为它们分配值,因为一旦完成 definePropertyObject.seal,就无法再更改它们。

我想我也可能会以略微不同的方式使用该白名单属性数组,只需循环遍历该数组即可。

所以:

export default class User {
    static getMembers() {
        return ['username','email','fullname','birthdate'];
    }

    constructor(props) {
        // Create the properties
        User.getMembers().forEach((name) => { this[name] = props[name]; });

        // Make sure username and email have a value, because we won't
        // be able to change it in a moment
        // ...

        // Make username and email read-only
        Object.defineProperty(this, "username", {writeable: false});
        Object.defineProperty(this, "email", {writeable: false});

        // Seal the object
        Object.seal(this);
    }
}