pig's diary

何でも忘れるので万年初心者ね

ビットマスクによるフラグ

参考:goog.ui.Control

複数の状態(STATE)を、1つの変数で保持する。例えば、DISABLED状態であり、同時にHOVER状態でもある状態を1つの変数で表現する。以下、そのときのフラグの上げ下げのしかた。

まずビットマスクに使う定数を用意する。1,2,4,8,16,32...とする。

/**
 * @enum {number}
 */
var STATE = {
  DISABLED: 1,
  HOVER: 2,
  ACTIVE: 4,
  FOCUSED: 8
};

/**
 * @type {number}
 */
var state  = 0;

フラグが上がっているかの確認。if文で使うときは、 if (state & STATE.DISABLED) で判定できる。まだ、どのフラグも上がってない。

console.log(!!(state & STATE.DISABLED));  // false
console.log(!!(state & STATE.HOVER));     // false
console.log(!!(state & STATE.ACTIVE));    // false
console.log(!!(state & STATE.FOCUSED));   // false

それでは、2つのフラグを上げてみる。STATE.DISABLEDとSTATE.HOVERだけ。2つのやり方があり、同じ意味。

state |= STATE.DISABLED;
state = state | STATE.HOVER;

console.log(!!(state & STATE.DISABLED));  // true
console.log(!!(state & STATE.HOVER));     // true
console.log(!!(state & STATE.ACTIVE));    // false
console.log(!!(state & STATE.FOCUSED));   // false

他のフラグには影響を与えていないのが分かる。

次に、挙げたフラグを、下げてみる。これにも2つやり方があり、同じ意味。

state &= ~STATE.DISABLED;
state = state & ~STATE.HOVER;

console.log(!!(state & STATE.DISABLED));  // false
console.log(!!(state & STATE.HOVER));     // false
console.log(!!(state & STATE.ACTIVE));    // false
console.log(!!(state & STATE.FOCUSED));   // false

続いて、いっぺんに複数のフラグを上げてみる。

state = STATE.DISABLED | STATE.HOVER | STATE.ACTIVE;

console.log(!!(state & STATE.DISABLED));  // true
console.log(!!(state & STATE.HOVER));     // true
console.log(!!(state & STATE.ACTIVE));    // true
console.log(!!(state & STATE.FOCUSED));   // false

上記は、初期値の時点でいくつかのフラグを上げておきたいときなどに使える。代入文であることからも分かるように、元のフラグを無視して上書きする。

全てのフラグを下げるには、0を代入する。

state = 0;

console.log(!!(state & STATE.DISABLED));  // false
console.log(!!(state & STATE.HOVER));     // false
console.log(!!(state & STATE.ACTIVE));    // false
console.log(!!(state & STATE.FOCUSED));   // false