javascript对象中的互斥布尔值?

javascript对象中的互斥布尔值?,javascript,Javascript,我有一个带有3个布尔值的javascript对象: var obj = {}; obj.isPrimary = true; obj.isPromotion = false; obj.isSocial = false; 其中只有一个是真的,永远不会有超过1个是真的。如何实现这一点?您可以使用以下方法: Object.defineProperty(obj, 'isPrimary', { get: function(){ return !this.isPromotion

我有一个带有3个布尔值的javascript对象:

var obj = {};
obj.isPrimary = true;
obj.isPromotion = false;
obj.isSocial = false;
其中只有一个是真的,永远不会有超过1个是真的。如何实现这一点?

您可以使用以下方法:

 Object.defineProperty(obj, 'isPrimary', {
    get: function(){ 
       return  !this.isPromotion && !this.isSocial; //<-- Your logic goes here.
    }
 });
Object.defineProperty(对象“isPrimary”{
get:function(){

return!this.isPromotion&&!this.isSocial;//使用getter/setter应该实现以下功能:

var obj={
设置一级(bool){
this.Primary=bool;
如果(bool){
这个。提升=这个。社交=错误;
}
},
集合isSocial(布尔){
这个社会=布尔;
如果(bool){
this.Promotion=this.Primary=false;
}
},
设置isPromotion(bool){
这个。提升=布尔;
如果(bool){
this.Primary=this.Social=false;
}
},
get isPrimary(){返回this.Primary;},
get-isSocial(){返回this.Social;},
get isPromotion(){返回此.Promotion;}
}
obj.isPrimary=true;
obj.isSocial=true;
obj.isPromotion=true;
警报(对象是主要的+''+对象是社会的+''+对象是建议的);

//false false true(因此只有'obj.isPromotion'是真的)
闭包是你的朋友。它们防止有人篡改内部状态

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

你可以用这样的函数来模拟

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的下一个倍数扩展
选项
对象。

您可以创建一个负责一次允许单个标志为真的对象。这将使
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; }
};

使用适当切换属性的getter和setter。不过,您仍然可以直接更新值。我说更简单的方法是实现一个类,并为两个变量实现getter和setter。更改一个变量会自动更改另一个变量。是否也可以只在函数中执行此操作?例如,设置一个变量会只需将其他值更改为false。
3
发生了什么事P@Cerbrus也许有一天他想改变他的逻辑。有了1,2,4,8,…他可以使用数字作为标志字段。我很确定bitmasks现在真的不是OP想要的。