开发者问题收集

在 setter 中检查值

2016-04-22
1257

是否可以在 es6 类属性 setter 中实现值验证? 愚蠢的尝试失败,如预期那样出现 Uncaught RangeError: Maximum call stack size reached :

class Something {
    constructor() {
        this.maxRange = 5;
        this.minRange = 1;
        this.selectedRange = 3;
    }
    set selectedRange(value) {
        if (value <= this.maxRange && value >= this.minRange) {
            this.selectedRange = value;
        }
    }
}

但是什么才是正确的方法?在 setter 中是否可以做到?(不使用 setPropsetRange 等附加方法)

2个回答

据我所知(欢迎指正),您不能将 setter(或 getter)与常规值混合使用。常规值将被覆盖。

Getter 和 setter 是访问器描述符的一部分,而常规值是数据描述符的一部分。

您需要同时使用 setter 和 getter,并定义一个内部属性(例如带有下划线 _ ),该属性由 getter 获取并由 setter 写入。

class Something {
    constructor() {
        this.maxRange = 5;
        this.minRange = 1;
        this._selectedRange = 3;
    }
    get selectedRange() {
        return this._selectedRange;
    }
    set selectedRange(value) {
        if (value <= this.maxRange && value >= this.minRange) {
            this._selectedRange = value;
        }
    }
}

您甚至可以将内部属性设为不可枚举,这样它就不会出现在循环中:

class Something {
    constructor() {
        this.maxRange = 5;
        this.minRange = 1;
        Object.defineProperty(this, '_selectedRange', {
            value: 3,
            configurable: true,
            writable: true,
            enumerable: false
        });
    }
    get selectedRange() {
        return this._selectedRange;
    }
    set selectedRange(value) {
        if (value <= this.maxRange && value >= this.minRange) {
            this._selectedRange = value;
        }
    }
}
nils
2016-04-22

首先,您应该明白,设置 selectedRange 的值时,set 总是会被调用。因此,您不应在“set”函数内设置 selectedRange 的值,否则它将陷入无限循环,导致超出最大调用堆栈大小错误。 因此请按如下方式操作

class Something {
    constructor() {
        this.maxRange = 5;
        this.minRange = 1;
        this.selectedRange = 3;
    }
    set selectedRange(value) {
        if (value <= this.maxRange && value >= this.minRange) {
            return true;
        }
    }
} 
S Vinesh
2016-04-22