Javascript 位掩码

Javascript bit masks

我以前在 Java(不是 Java脚本)中使用过位掩码,但是已经有一段时间了,这让我很困惑。

这是我想要使用的 Typescript。有 3 个角色,

enum Type {
    FRUIT = 0x1,
    VEGGIE = 0x2,
    BOTH = FRUIT | VEGGIE
}

class Thing {
    role:number;

    constructor(role:Type){
        this.role = role;
    }
    getRole(){
        return this.role;
    }
    is(role:Type) {
        return !!(this.role & role);
    }
}

var whatever = new Thing(Type.FRUIT);

console.log('fruit', whatever.is(Type.FRUIT));
console.log('veggie', whatever.is(Type.VEGGIE));
console.log('both', whatever.is(Type.BOTH));

// fruit true
// veggie false
// both true

我从概念上明白为什么 "both" 会以 "true" 的形式回归,但我的数学不是很好。

当角色为FRUITVEGGIE时,其他为false。当它设置为 BOTH 时,所有内容都应为真。

尝试了几种移位和位运算的组合,但我无法获得该输出。如果我尝试将它们分开,那很好,但我想使用位组合来构建。

return !!(this.role & role);

您的版本作为 isAny 使用,但您希望它作为 isAll:

使用
return (this.role & role) === role;

当您执行按位 & 运算时,结果是在表达式中使用的两个值中打开的位。

例如(摘自 Pro TypeScript,第 207 页)

a 1011
&
b 1101
= 1001

第一列,两个值都是"switched on (1)",所以结果也是开启的。第二列 a 关闭,所以结果是 0,第三列 b 关闭,所以再次 0 最后最后一列都打开, 所以 1.

在你的情况下,它更简单,因为你正在处理如此小的数字......

a 01 // FRUIT
&
b 11 // ALL
= 01 // FRUIT

所以结果是01,或者如果你有十根手指1

如果你使用双爆炸 !!1 转换为布尔值(我称之为 slacker parsing),你将得到 true 因为 1 是真实的。这并没有回答您真正要问的问题,即 "does this bit flag match".

这就是为什么 this.role & role === role 是正确的代码,因为您不会从值 1 的 "truthiness" 中得到错误。