2014-09-30 4 views
1

У меня есть JavaScript Object с 3 булевы:Взаимно эксклюзивные булевы в объекте javascript?

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

только один из них может быть правдой, что никогда не может быть случай, когда более 1 верно. Как я могу это достичь?

+0

Используйте геттеры и сеттеры, которые соответствующим образом переключают свойства. Тем не менее, вы все равно сможете обновлять значения. – Mathletics

+0

Я говорю, что проще будет реализовать класс, а также getter & setter для обеих переменных. Изменение одного автоматически изменило бы другое. – tfrascaroli

+0

Можно ли просто сделать это в функции? Например, установка одного только изменит остальные на false. – xaisoft

ответ

1

Вы можете использовать Object.defineProperty что-то вроде:

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

Конечно логика отключая эту опцию и выключать его до вас.

2

Использование геттер/сеттер должен сделать трюк:

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)

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 
+1

Что случилось с '3'? : P – Cerbrus

+0

@Cerbrus Возможно, он хочет изменить свою логику когда-нибудь. С 1, 2, 4, 8, ... он может использовать число в качестве поля флага. – dusky

+0

Я почти уверен, что битмаски действительно не то, что ищет OP на данный момент. – Cerbrus

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 

Если вам требуется больше вариантов, которые будут добавлены, то вы можете просто расширить объект options новыми значениями и следующий кратный 2.

0

Вы может создать объект, ответственный за то, что один флаг может быть истинным одновременно. Это избавит ваш 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; } 
}; 
Смежные вопросы