javascript对象中互斥的布尔值?

时间:2014-09-30 14:31:23

标签: javascript

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

var obj = {};
obj.isPrimary = true;
obj.isPromotion = false;
obj.isSocial = false;

其中只有一个是真的,永远不会有超过1的情况。我怎样才能做到这一点?

5 个答案:

答案 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; }
};