2014-09-30 47 views
1

我有3個布爾一個JavaScript對象:JavaScript對象中的互斥布爾值?

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

只有這些人可以是真實的,永遠不會有多於1是真實的情況。我怎樣才能做到這一點?

+0

使用適當切換屬性的getter和setter。您仍然可以直接更新值。 – Mathletics 2014-09-30 14:32:40

+0

我說更簡單的方法是實現一個類,併爲這兩個變量設置getter&setter。改變一個會自動改變另一個。 – tfrascaroli 2014-09-30 14:33:17

+0

也可以在一個函數中做到這一點?例如,設置其中一個只會將其他設置改爲false。 – xaisoft 2014-09-30 14:36:32

回答

1

您可以使用Object.defineProperty類似:

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

當然後面打開和關閉它是由你切換此選項的邏輯。

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)

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 2014-09-30 14:46:28

+0

@Cerbrus也許他想在某一天改變自己的邏輯。用1,2,4,8 ...,他可以使用該號碼作爲標誌字段。 – dusky 2014-09-30 14:49:59

+0

我很確定bitmasks真的不是OP目前正在尋找的東西。 – Cerbrus 2014-10-01 07:01:04

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對象。

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