首页 > 解决方案 > 在 JS ES6 类中强制使用 setter 而不是直接赋值

问题描述

我有一个看起来像这样的 CameraBuilder 类:

class CameraBuilder {
    constructor() {
        if (arguments.length) {
            throw new Error('[CameraBuilder constructor ERROR] class constructor does not accept parameters.');
        }
        this.camera = {};
    }

    withFarmLabel(farmLabel) {
        this.camera.farm_label = farmLabel;
        return this;
    }

    // more methods here

    build() {
        const missingProps = [];
        if (!this.camera.farm_label) {
            missingProps.push('\nMissing farm_label property. Use the withFarmLabel method in order to assign it.');
        }
        
        // more validations like the one above here

        if (missingProps.length) {
            const errorMsg = missingProps.join('');
            throw new Error(`[CameraBuilder build ERROR] ${errorMsg}`);
        }

        return this.camera;
    }
}

由于我的大部分验证都在build()方法上,并且其中一些方法上存在一些与用户如何构建 CameraBuilder 实例相关的业务逻辑,因此我不希望任何人cameraBuilderObj.camera直接分配。有什么方法可以强制使用 Class 方法来将属性分配给 Camera 对象?

标签: javascriptnode.jsecmascript-6

解决方案


您可以通过将camera属性放在它前面来将其设为私有#,确保只有CameraBuilder' 的内部可以引用它:

class CameraBuilder {
    #camera = {};
    constructor() {
        if (arguments.length) {
            throw new Error('[CameraBuilder constructor ERROR] class constructor does not accept parameters.');
        }
    }

    withFarmLabel(farmLabel) {
        this.#camera.farm_label = farmLabel;
        return this;
    }

    // more methods here

    build() {
        const missingProps = [];
        if (!this.#camera.farm_label) {
            missingProps.push('\nMissing farm_label property. Use the withFarmLabel method in order to assign it.');
        }
        
        // more validations like the one above here

        if (missingProps.length) {
            const errorMsg = missingProps.join('');
            throw new Error(`[CameraBuilder build ERROR] ${errorMsg}`);
        }

        return this.#camera;
    }
}

const c = new CameraBuilder();
c.withFarmLabel('label');
console.log(c.camera);
console.log(c.build().farm_label);


推荐阅读