2015-11-12 3 views
0

Я пытаюсь объединить двоичные флаги javascript inline с моим определением var, но мой код генерирует исключение «Невозможно найти переменную: A». Есть ли способ сделать это?Javascript Combine Binary Flags

var flag = { 
    A: 1, 
    B: 2, 
    C: 4, 
    D: 8, 
    All: A | B | C | D, 
}; 
+0

Это не проблема с вашей математикой, это проблема с тем, как вы декларируете вещи. Вы не можете использовать 'A', пока вы все еще объявляете объект, содержащий' A'. – ssube

ответ

6

Вы не можете использовать A в то время как вы все еще объявляя объект, который содержит A.

Если вы хотите использовать эти значения, вам необходимо объявить (или инициализировать) All поле позже, например, так:

var flag = { 
    A: 1, 
    B: 2, 
    C: 4, 
    D: 8, 
}; 
flag.All = flag.A | flag.B | flag.C | flag.D; 

В качестве альтернативы, вы можете использовать функцию в качестве рамки вложить переменные, и сделать что-то вроде:

var flag = (function() { 
    var A = 1, B = 2, C = 4, D = 8; 
    return {A: A, B: B, C: C, D: D, All: A|B|C|D}; 
}()); 

объект сокращенная ES6 делает это гораздо более привлекательным:

var flag = (function() { 
    var A = 1, B = 2, C = 4, D = 8; 
    return {A, B, C, D, All: A|B|C|D}; 
}()); 

Если All это общий шаблон для вас, то можно произвести, что:

flag.All = Object.keys(flag).reduce(function (p, c) { 
    return p | flag[c]; 
}, 0); 

С ES6, вы можете сократить, что, как хорошо:

flag.All = Object.keys(flag).reduce((p, c) => (p | flag[c]), 0); 

Если ES6 доступна для вас, попробуйте this answer для объявления перечислений. Вышеупомянутые методы для создания значения All будут работать с ним, но он обеспечивает больше традиционной семантики перечисления, которую вы могли бы ожидать (особенно для чтения).

+0

Отличные ответы. Я не пробовал их всех. Первый работает, но становится длинным, когда у меня много флагов и описательных имен. Любите вариант уменьшения! Это я добавлю в свою панель инструментов. Благодарю. –