web-dev-qa-db-fra.com

Énumérer les drapeaux en JavaScript

J'ai besoin d'émuler le type d'énumération en Javascript et l'approche semble assez simple:

var MyEnum = {Left = 1; Right = 2; Top = 4; Bottom = 8}

Maintenant, en C #, je pouvais combiner ces valeurs comme ceci:

MyEnum left_right = MyEnum.Left | MyEnum.Right

puis je peux tester si enum a une certaine valeur:

if (left_right & MyEnum.Left == MyEnum.Left) {...}

Puis-je faire quelque chose comme ça en Javascript?

45
Andrey

En javascript, vous devriez pouvoir les combiner comme:

var left_right = MyEnum.Left | MyEnum.Right;

Le test serait alors exactement comme dans votre exemple de

if ( (left_right & MyEnum.Left) == MyEnum.Left) {...}
48
Mike Clark

Il vous suffit d'utiliser les opérateurs au niveau du bit :

var myEnum = {
  left: 1,
  right: 2,
  top: 4,
  bottom: 8
}

var myConfig = myEnum.left | myEnum.right;

if (myConfig & myEnum.right) {
  // right flag is set
}

Plus d'informations:

76
CMS

Oui, l'arithmétique au niveau du bit fonctionne en Javascript. Vous devez être prudent avec cela car Javascript n'a que le type de données Number, qui est implémenté comme un type à virgule flottante. Mais, les valeurs sont converties en signé valeurs 32 bits pour les opérations au niveau du bit. Donc, tant que vous n'essayez pas d'utiliser plus de 31 bits, tout ira bien.

10
Warren Young

J'ai essayé de créer un exemple qui illustre un cas d'utilisation courant où l'on peut utiliser des énumérations de masque de bits pour contrôler la verbosité de la journalisation. Il illustre les opérations binaires en JavaScript: Voir sur JSFiddle

/*
 * Demonstration of how a Flags enum can be simulated in JavaScript and 
 * Used to control what gets logged based on user passed value
 */

// A Flags Enum (sort-of)
var LogLevels = {
    NONE: 0,
    INFO: 1,
    TRACE: 2,
    DEBUG: 4,
    WARN: 8,
    ERROR: 16,
    FATAL: 32
};

// Initialize
var currLogLevel = LogLevels.NONE;

// User Sets a log level
var logLevel = LogLevels.WARN;

// Convert the configured logLvel to a bit-masked enum value
switch (logLevel) {
    case LogLevels.INFO:
        currLogLevel = LogLevels.INFO | LogLevels.TRACE | LogLevels.DEBUG | LogLevels.WARN | LogLevels.ERROR | LogLevels.FATAL;
        break;
    case LogLevels.TRACE:
        currLogLevel = LogLevels.TRACE | LogLevels.DEBUG | LogLevels.WARN | LogLevels.ERROR | LogLevels.FATAL;
        break;
    case LogLevels.DEBUG:
        currLogLevel = LogLevels.DEBUG | LogLevels.WARN | LogLevels.ERROR | LogLevels.FATAL;
        break;
    case LogLevels.WARN:
        currLogLevel = LogLevels.WARN | LogLevels.ERROR | LogLevels.FATAL;
        break;
    case LogLevels.ERROR:
    case LogLevels.FATAL:
    default:
        currLogLevel = LogLevels.ERROR | LogLevels.FATAL;
}

// Example: log verbosity set to WARN, so this would NOT be logged
if ((currLogLevel & LogLevels.DEBUG) == LogLevels.DEBUG) {
    console.log("log DEBUG");
}
5
Sudhanshu Mishra