我有一个包含3个布尔值的javascript对象:
var obj = {};
obj.isPrimary = true;
obj.isPromotion = false;
obj.isSocial = false;
其中只有一个是真的,永远不会有超过1的情况。我怎样才能做到这一点?
答案 0 :(得分:2)
使用getter / setter应该可以解决问题:
var obj = {
set isPrimary(bool){
this.Primary = bool;
if(bool){
this.Promotion = this.Social = false;
}
},
set isSocial(bool){
this.Social = bool;
if(bool){
this.Promotion = this.Primary = false;
}
},
set isPromotion(bool){
this.Promotion = bool;
if(bool){
this.Primary = this.Social = false;
}
},
get isPrimary(){ return this.Primary; },
get isSocial(){ return this.Social; },
get isPromotion(){ return this.Promotion; }
}
obj.isPrimary = true;
obj.isSocial = true;
obj.isPromotion = true;
alert(obj.isPrimary + ' ' + obj.isSocial + ' ' + obj.isPromotion);
// false false true (So only `obj.isPromotion` is true)
答案 1 :(得分:1)
您可以使用Object.defineProperty
之类的内容:
Object.defineProperty(obj, 'isPrimary', {
get: function(){
return !this.isPromotion && !this.isSocial; //<-- Your logic goes here.
}
});
当然,打开和关闭此选项背后的逻辑取决于你。
答案 2 :(得分:0)
闭包是你的朋友。他们阻止有人可以摆弄内部状态。
function createPropObj() {
var props = 0;
return {
get isPrimary() { return props === 1; },
set isPrimary(val) { if (val) { props = 1; }; },
get isPromotion() { return props === 2; },
set isPromotion(val) { if (val) { props = 2; }; },
get isSocial() { return props === 4; },
set isSocial(val) { if (val) { props = 4; }; }
}
}
你可以这样使用它:
> var test = createPropObj();
undefined
> test.isPrimary = true;
true
> test.isPromotion = true;
true
> test.isPrimary
false
答案 3 :(得分:0)
你可以用这样的函数来模拟这个
function createToggleValues() {
var options = {
"primary": 1,
"promotion": 2,
"social": 4
},
value = 0;
return {
"set": function(name) {
value = options[name];
},
"is": function(name) {
return (value & options[name]) === options[name];
}
}
};
var togglable = createToggleValues();
togglable.set("primary");
console.log(togglable.is("primary"));
// true
如果您需要添加更多选项,那么您可能只想使用新值和下一个2的倍数扩展options
对象。
答案 4 :(得分:0)
您可以创建一个对象,负责一次允许单个标志为true。这将减轻您obj
实施该逻辑的麻烦。在下面的示例中,SingleTrueFlagGroup
保留了一组标志,允许一个标志一次为真。然后,您的obj
可以在此对象的实例上进行双重调度,以完成工作。
类似实现的优点是添加和删除标志变得微不足道。
var flags = ['isPrimary', 'isPromotion', 'isSocial'],
obj = {
_flags: new SingleTrueFlagGroup(flags)
};
flags.forEach(function (flag) {
Object.defineProperty(obj, flag, {
get: function () { return this._flags.get(flag); },
set: function (value) { this._flags.set(flag, value); }
});
});
obj.isPrimary = true;
obj.isPromotion = true;
console.log(obj.isPrimary); //false
console.log(obj.isPromotion); //true
function SingleTrueFlagGroup(flags) {
this._flags = {};
(flags || []).forEach(this.add.bind(this));
}
SingleTrueFlagGroup.prototype = {
constructor: SingleTrueFlagGroup,
set: function (flagToSet, value) {
var flags = this._flags;
(flags[flagToSet] = !!value) && Object.keys(flags).forEach(function (flag) {
if (flag !== flagToSet) flags[flag] = false;
});
},
get: function (flag) { return this._flags[flag]; },
add: function (flag) { this._flags[flag] = false; }
};